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 5

Publicado en el grupo Random-ES
¡Hola hola! Los desarrolladores de Java tienen una gran demanda en la actualidad. Por supuesto, no puedo ofrecerle una oferta de trabajo, pero intentaré ayudarle a adquirir nuevos conocimientos y llenar algunos vacíos. Entonces, continuemos con nuestra revisión de las preguntas de la entrevista para desarrolladores de Java. Puede encontrar enlaces a las partes anteriores de la revisión al final del artículo. Explorando preguntas y respuestas de una entrevista de trabajo para un puesto de desarrollador de Java.  Parte 5 - 1

39. ¿Cuáles son los modificadores de acceso en Java? Nómbralos. ¿Para qué se usan?

Anteriormente cubrí los modificadores de acceso en una pregunta sobre los elementos de Java utilizados para lograr la encapsulación. Pero aún así te lo recordaré. Los modificadores de acceso en Java son palabras clave que describen el nivel de acceso otorgado a un componente Java en particular. Existen los siguientes modificadores de acceso:
  • público : un elemento marcado con este modificador es público. En otras palabras, los campos, métodos y clases declarados con el modificador público son visibles para otras clases tanto en su propio paquete como en paquetes externos;
  • protegido : se puede acceder a un elemento marcado con este modificador desde cualquier lugar de su propia clase en el paquete actual o clases derivadas, incluso si están en otros paquetes;
  • default (o ningún modificador) se aplica implícitamente cuando no se indica ningún modificador de acceso. Es similar al anterior, excepto que es visible en clases derivadas que se encuentran en otros paquetes;
  • privado : este es el más privado de todos los modificadores. Permite el acceso a un elemento sólo dentro de la clase actual.

40. Nombra las características principales de los métodos estáticos y no estáticos.

La principal diferencia es que los métodos estáticos pertenecen a una clase. De hecho, no es necesario crear una instancia de esta clase; los métodos estáticos se pueden llamar solo desde el tipo de clase. Por ejemplo, supongamos que tenemos un método estático para acariciar a un gato:
public class CatService {
   public static void petTheCat(Cat cat) {
       System.out.println("Pet the cat: " + cat.getName());
   }
No necesitamos una instancia de la clase CatService para llamarlo:
Cat cat = new Cat(7, "Bobby");
CatService.petTheCat(cat);
Por el contrario, los métodos ordinarios están vinculados (pertenecen) a un objeto. Para llamarlos, debe tener una instancia (objeto) en la que se llamará el método. Por ejemplo, supongamos que nuestro gato tiene un método no estático meow() :
class Cat {
   public void meow() {
       System.out.println("Meow! Meow! Meow!");
   }
Para llamar a este método, necesitamos una instancia específica de un gato:
Cat cat = new Cat(7, "Bobby");
cat.meow();

41. ¿Cuáles son las principales restricciones que se aplican a los métodos estáticos y no estáticos?

Como dije antes, la principal limitación de un método ordinario (no estático) es que siempre debe haber alguna instancia en la que se llame al método. Pero un método estático no requiere esto. Además, un método estático no puede utilizar esta referencia a elementos de un objeto ya que ahora existe un objeto actual para el método.

42. ¿Qué significa la palabra clave estática? ¿Se puede anular o sobrecargar un método estático?

Un elemento marcado con la palabra clave estática no pertenece a una instancia de una clase sino a la clase misma. Se carga cuando se carga la clase misma. Los elementos estáticos son los mismos para todo el programa, mientras que los elementos no estáticos son iguales sólo para un objeto específico. Los siguientes elementos pueden ser estáticos:
  • campos de una clase;
  • bloque de inicialización de una clase;
  • un método de una clase;
  • clases anidadas de una clase (por supuesto, esto también es una tautología).
Un método estático no se puede anular: pertenece a la clase y no se hereda, pero al mismo tiempo se puede sobrecargar.

43. ¿Puede un método ser estático y abstracto al mismo tiempo?

Esto ya lo respondí en un artículo anterior: un método no puede ser abstracto y estático al mismo tiempo. Si un método es abstracto, eso implica que debe anularse en una clase secundaria. Pero un método estático pertenece a la clase y no se puede anular. Esto crea una contradicción que el compilador notará y se enojará. Si se encuentra en esta situación, debería pensar seriamente en la corrección de la arquitectura de su aplicación (pista: claramente algo anda mal). Explorando preguntas y respuestas de una entrevista de trabajo para un puesto de desarrollador de Java.  Parte 5 - 2

44. ¿Se pueden utilizar métodos estáticos en medio de métodos no estáticos? ¿Y viceversa? ¿Por qué?

Podemos utilizar métodos estáticos en métodos no estáticos. Nada lo impide. Dicho esto, lo contrario no es posible: un método estático no puede utilizar un método no estático sin hacer referencia a una instancia específica de la clase. Recuerde, los miembros estáticos de una clase no tienen acceso a esta referencia: puede tener tantos objetos concretos de la clase como desee, y cada uno de ellos contendrá una referencia esta , que es una autorreferencia. Entonces, ¿cómo determinar cuál referencia utilizar? Eh, no lo haces. Es por eso que los elementos estáticos no pueden referirse a los no estáticos sin una referencia a un objeto específico. Básicamente, un método estático puede utilizar un método no estático sólo si tiene una referencia a un objeto específico. Por ejemplo, uno que apareció como argumento de método:
public static void petTheCat(Cat cat) {
   System.out.println("Pet the cat: " + cat.getName());
}
Aquí vemos que en el método estático petTheCat() llama a getName , un método ordinario no estático de un objeto Cat .

45. ¿Qué es una interfaz? ¿Puede haber una interfaz final?

Recordaremos que Java no tiene herencia múltiple. Las interfaces son una especie de alternativa. Una interfaz es como una clase muy simplificada. Definen la funcionalidad pero no una implementación concreta. Esa tarea se deja a las clases que implementan estas interfaces. Ejemplo de una interfaz:
public interface Animal {
    void speak();
}
Ejemplo de implementación de una interfaz por parte de una clase
class Cat implements Animal {

   @Override
   public void speak() {
       System.out.println("Meow! Meow! Meow!");
   }
}
Esto es lo más importante que debe saber sobre el uso de interfaces:
  1. Los métodos de interfaz solo deben contener un encabezado. No deben tener un cuerpo de método específico, es decir, deben ser abstractos (aunque no utilicen la palabra clave abstract ). Hay excepciones: métodos estáticos y métodos predeterminados, que requieren un cuerpo de método.

  2. Una clase puede implementar muchas interfaces (como dije, las interfaces son una alternativa a la herencia múltiple). Los nombres de las interfaces están separados por comas en el encabezado del método: clase Lion implements Animal, Wild .

  3. Las interfaces se crean utilizando la palabra clave interface .

  4. Cuando una clase implementa una interfaz, usamos la palabra clave implements .

  5. Una clase que implementa una determinada interfaz debe implementar todos sus métodos abstractos o debe declararse abstracta.

  6. El objetivo principal del uso de interfaces es implementar polimorfismo (darle a un objeto la capacidad de adoptar muchas formas).

  7. Como regla general, los modificadores de acceso a los métodos no se indican en las interfaces: son públicos de forma predeterminada y no se pueden especificar modificadores que no sean públicos . A partir de Java 9, puede utilizar modificadores privados en los métodos.

  8. De forma predeterminada, las variables de la interfaz son estáticas finales . En otras palabras, son constantes: siempre deben inicializarse directamente en la interfaz.

  9. No se puede crear una instancia de una interfaz.

La respuesta a la pregunta de si las interfaces pueden ser definitivas es, por supuesto, no. De hecho, el objetivo de tener interfaces es que se implementen. Y como todos recordamos muy bien, el modificador final a nivel de clase hace que una clase no sea heredable y, en el caso de una interfaz, no implementable. ¿Por qué necesitaríamos una interfaz que no podemos implementar ni utilizar? Tienes razón: ¡no lo haríamos! Y el compilador está de acuerdo. :) Explorando preguntas y respuestas de una entrevista de trabajo para un puesto de desarrollador de Java.  Parte 5 - 3En realidad, con la introducción de métodos de interfaz estáticos desde Java 8, puede que tenga sentido, pero esto no cambia el hecho de que una interfaz no puede ser definitiva. Sólo he hablado de interfaces de forma muy superficial, ya que se trata de un tema amplio. Para obtener más información sobre esto, consulte los artículos sobre interfaces en Java y la diferencia entre clases abstractas e interfaces .

46. ​​¿Dónde se pueden inicializar los campos estáticos?

Los campos estáticos se pueden inicializar:
  • inmediatamente después de la declaración, utilizando un signo igual ( = );
  • en un bloque de inicialización estático;
  • en un bloque de inicialización no estático (pero debe comprender que cada vez que se crea un objeto, el campo estático se sobrescribirá cuando se ejecute este bloque de inicialización;
  • en un constructor de clases. Cada vez que se llama al constructor (es decir, cada vez que se crea un objeto usando este constructor), el campo se sobrescribirá;
  • en métodos estáticos;
  • en métodos no estáticos;
  • en clases anidadas estáticas y no estáticas, locales y anónimas.

47. ¿Qué son las clases anónimas?

Las clases anónimas son clases que no tienen su propio tipo. ¿De qué estoy hablando? Cuando hablamos de interfaces, mencioné que no se podía crear una instancia de un objeto: sólo se podía crear una instancia de una clase que implementaba una interfaz. ¿Qué sucede si no desea que alguna clase implemente una interfaz pero necesita un objeto que implemente la interfaz? Y es probable que éste sea el único uso del objeto. Y no es necesario crear una clase de implementación completa. ¿Como lo harias? ¡Así es! ¡Usando una clase anónima! Explorando preguntas y respuestas de una entrevista de trabajo para un puesto de desarrollador de Java.  Parte 5 - 4Supongamos que tenemos alguna interfaz Animal :
public final interface Animal {
   public void speak();
}
Si queremos utilizar una clase anónima para crear una instancia de una interfaz determinada:
Animal cat = new Animal() {
   @Override
   public void speak() {
       System.out.println("Meow! Meow! Meow!");
   }
};
Y luego, puede utilizar de forma segura este objeto y su método talk() implementado . En otras palabras, la clase anónima implementa la interfaz y todos sus métodos abstractos, aquí y ahora. De lo contrario, no podríamos crear una interfaz/objeto de clase abstracta ya que habría métodos abstractos/no implementados. Como mencioné, las clases anónimas se usan no solo para implementar los métodos abstractos de una interfaz sino también para implementar los métodos abstractos de una clase abstracta. Este enfoque es bueno para situaciones en las que un objeto se usa una vez o cuando la implementación de un método determinado solo se necesita una vez. No es necesario crear una clase separada que implemente la clase/interfaz abstracta requerida. Pero también observo que las clases anónimas rara vez se utilizan en el trabajo. Por regla general, se siguen dando preferencia a las clases ordinarias. Puede leer más sobre las clases anónimas aquí en este artículo .

48. ¿Qué son las clases primitivas?

Creo que esta es una pregunta engañosa, posiblemente una pregunta capciosa, ya que Java no tiene clases primitivas. Sólo existe el concepto de tipos primitivos, que consideramos anteriormente. Recordamos que Java tiene 8 tipos primitivos: byte , short , int , long , float , double , char , boolean .

49. ¿Qué es una clase contenedora?

El principal problema con el uso de tipos primitivos en Java es que no son clases y Java es un lenguaje OOP. Es decir, los programas escritos en este lenguaje equivalen a interacciones entre objetos. Pero los primitivos no son objetos. No tienen métodos, ni siquiera los métodos estándar de la clase Objeto . Pero ¿qué pasa si necesitamos usar una primitiva como clave en un mapa ? Luego necesitamos llamar a su método hashCode() . También puedes llamar a su método equals() allí. ¿Entonces que? Hay montones y montones de momentos en los que necesitas una clase, no un primitivo. Esto convierte a las primitivas en elementos inutilizables e indeseables en un programa porque violan la idea misma de POO. Pero la situación no es tan mala como parece. Después de todo, Java tiene el concepto de envoltorios primitivos. En Java, cada tipo primitivo tiene un gemelo: una clase contenedora.
  • byte -> Byte.clase
  • corto -> Clase corta
  • int -> Entero.clase
  • largo -> Clase larga
  • flotador -> Flotador.clase
  • doble -> Doble.clase
  • char -> Carácter.clase
  • booleano -> booleano.clase
Estos tipos representan tipos simples, pero en clases completas con un montón de métodos variados y útiles. Se introdujeron los conceptos de autoboxing y unboxing para permitir el uso conveniente de estas clases. Autoboxing es la conversión automática de un tipo primitivo a su clase análoga, si es necesario (por ejemplo, convertir int a Integer ). Unboxing es el proceso opuesto: conversión automática de una clase contenedora primitiva a un tipo primitivo (por ejemplo, convertir Integer a int ). Gracias a la introducción de clases contenedoras primitivas y los procesos de autoboxing y unboxing , los tipos primitivos ahora son miembros de pleno derecho de Java como lenguaje OOP. Explorando preguntas y respuestas de una entrevista de trabajo para un puesto de desarrollador de Java.  Parte 5 - 5Para una discusión más profunda sobre este tema, recomiendo encarecidamente leer este artículo .

50. ¿Qué es una clase anidada? ¿Dónde se usa?

Una clase anidada es una clase que es en sí misma miembro de otra clase. Hay 4 tipos de clases anidadas en Java: 1. Clase interna Este tipo de clase se declara directamente en el cuerpo de otra clase. Una clase interna es una clase anidada no estática y puede acceder a cualquier campo privado o método de instancia de la clase externa. Como ejemplo, creemos un zoológico que contenga un animal: una cebra:
public class Zoo {
   class Zebra {
       public void eat(String food) {
           System.out.println("Zebra eats " + food);
       }
   }
}
No es complicado ¿verdad? Echemos un vistazo a un ejemplo de creación de una instancia de clase interna:
Zoo.Zebra zebra = new Zoo().new Zebra();
zebra.eat("apple");
Como ya has visto, primero es necesario crear un objeto de la clase adjunta. Luego usa la referencia del objeto para crear una instancia de la clase interna. También me gustaría señalar que una clase interna (clase anidada no estática) no puede tener métodos estáticos o campos estáticos. Esto se debe precisamente a que la clase interna está implícitamente asociada con una instancia de su clase externa y, por lo tanto, no puede declarar ningún método estático dentro de sí misma. 2. Clases anidadas estáticas Estas clases son similares a la categoría anterior, pero tienen el modificador de acceso estático en la declaración de clase. Dado que este tipo de clase no tiene acceso a los campos no estáticos de la clase externa, parece más una parte estática de la clase externa que una clase interna. Pero esta clase tiene acceso a todos los miembros estáticos de la clase externa, incluso los privados. Ejemplo de una clase anidada estática:
public class Zoo {
   static class Zebra {
       public void eat(String food) {
           System.out.println("Zebra eats " + food);
       }
   }
}
Está creado de una forma ligeramente diferente al anterior:
Zoo.Zebra zebra = new Zoo.Zebra();
zebra.eat("apple");
Aquí no necesitamos un objeto de la clase externa para crear un objeto de la clase anidada estática. Sólo necesitamos saber el nombre de la clase anidada para encontrarla dentro de la clase externa. 3. Clases locales Las clases locales son clases declaradas dentro del cuerpo de un método. Los objetos de una clase local se pueden crear y utilizar sólo dentro del método adjunto. Ejemplo:
public class Zoo {
   public void feed(String animal, String food) {
       switch(animal) {
           case "zebra":
               class Zebra {
                   public void eat(String food) {
                       System.out.println("Zebra eats " + food);
                   }
               }
               Zebra zebra = new Zebra();
               zebra.eat(food);
               ...
He aquí un ejemplo:
Zoo zoo = new Zoo();
zoo.feed("zebra", "apple");
Si no vieras el código del método feed() , ni siquiera sospecharías que existe una clase local, ¿verdad? Una clase local no puede ser estática o transitoria , pero se puede marcar como abstracta o final (una O la otra, pero no ambas, ya que el uso simultáneo de estos dos modificadores crea un conflicto). 4. Clases anónimas Ya hablamos anteriormente sobre las clases anónimas y, como recordará, se pueden crear a partir de dos fuentes: interfaces y clases. Razones para utilizarlas Se utilizan clases anidadas estáticas y no estáticas porque a veces es mejor integrar clases pequeñas en otras más generales y mantenerlas juntas para que tengan mayor cohesión y un propósito común. Básicamente, las clases anidadas te permiten aumentar la encapsulación de tu código. Puede optar por utilizar una clase local si la clase se utiliza exclusivamente dentro de un único método. En este caso, ¿necesitamos distribuir el código por la aplicación? No. Dicho esto, agregaré que en mi experiencia nunca he visto a nadie usar clases locales, porque si son necesarias o no es muy controvertido. Puede utilizar clases anónimas cuando una implementación específica de una interfaz o una clase abstracta solo se necesita una vez. En ese caso, no es necesario crear una clase independiente y completa con una implementación. En cambio, lo mantuvimos simple e implementamos los métodos que necesitábamos usando una clase anónima, usamos el objeto y luego nos olvidamos de él (por supuesto, el recolector de basura no lo olvidó). Su comprensión de las clases anidadas mejorará con el artículo aquí.

51. ¿Qué modificadores de acceso puede tener una clase?

Hay diferentes tipos de clases y se les aplican diferentes modificadores de acceso:
  • una clase externa puede tener el modificador de acceso público o ningún modificador (el modificador predeterminado);
  • una clase interna (clase anidada no estática) puede tener cualquiera de los 4 modificadores de acceso;
  • una clase estática anidada puede tener cualquiera de los modificadores de acceso excepto protected porque este modificador implica herencia, lo que contradice cualquier miembro estático de la clase (los miembros estáticos no se heredan);
  • una clase local sólo puede tener el modificador predeterminado (es decir, ningún modificador);
  • una clase anónima no tiene declaración de clase, por lo que no tiene ningún modificador de acceso.
Aquí es donde terminaremos por hoy. ¡Nos vemos pronto!Explorando preguntas y respuestas de una entrevista de trabajo para un puesto de desarrollador de Java.  Parte 5 - 6
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION