JavaRush /Java Blog /Random EN /Analysis of questions and answers from interviews for Jav...

Analysis of questions and answers from interviews for Java developer. Part 16

Published in the Random EN group
Hello, friend! How long does it take to become a developer? I asked a lot of different people and heard a lot of different answers. For some people even a month may be enough, but for others even a year will not be enough. But I know for sure that becoming a Java developer is a thorny and long path, regardless of your initial abilities. After all, it is not so much ability that is important as stubbornness and hard work. Analysis of questions and answers from interviews for Java developer.  Part 16 - 1Therefore, today we continue to purposefully analyze the most popular interview questions for Java developer. Studying them will gradually bring you closer to your cherished goal. Let's get started!

17. Give examples of successful and unsuccessful use of Optional

Suppose we have a certain series of values ​​through which we go through the stream, and in the end we get some Optional as a result:
Optional<String> stringOptional = Stream.of("a", "ab", "abc", "abcd")
   .filter(str -> str.length() >= 3)
   .findAny();
We, as expected, need to get the value from this Optional . Just using get() is a bad way:
String result = stringOptional.get();
But this method is supposed to get the value from Optional and return it to us? This is, of course, true, but if it has meaning. Well, if the values ​​in the stream were different, and in the end we received an empty Optional , when we try to take a value from it using the get() method, the following will be thrown: Analysis of questions and answers from interviews for Java developer.  Part 16 - 2Which is not good. In this case, it is better to use the following constructions:
  1. String result = null;
    if (stringOptional.isPresent()) {
     stringOptional.get();
    }

    In this case, we are checking to see if the element is in Optional . If not, the resulting string has its old value.

  2. String result = stringOptional.orElse("default value");

    In this case, we specify some default value, which will be given to the resulting string in the case of an empty Optional .

  3. String result = stringOptional.orElseThrow(() -> new CustomException());

    In this case, we ourselves throw an exception when Optional is empty .

This can be convenient in an application when, for example, the Spring JPA method is used - findById() , which returns Optional values. In this case, with this method we try to take the value, and if it is not there, we throw some Runtime exception, which is processed at the controller level using ExceptionHandler and converted into an HTTP response with the status 404 - NOT FOUND . Analysis of questions and answers from interviews for Java developer.  Part 16 - 3

18. Is it possible to declare a main method as final?

Yes, of course, nothing prevents us from declaring the main() method as final . The compiler will not produce errors. But it is worth remembering that any method after declaring it as final will become the last method - not overridden. Although, who will redefine main ??? Analysis of questions and answers from interviews for Java developer.  Part 16 - 4

19. Is it possible to import the same package/class twice? What could be the consequences?

Yes you can. Consequences? We will have a couple of unnecessary imports that Intelijj IDEA will display as gray, i.e. unused. Analysis of questions and answers from interviews for Java developer.  Part 16 - 5Analysis of questions and answers from interviews for Java developer.  Part 16 - 6

20. What is Casting? When can we get a ClassCastException?

Casting, or type casting , is the process of converting one data type to another data type: manually (implicit casting) or automatically (explicit type casting). Analysis of questions and answers from interviews for Java developer.  Part 16 - 7Automatic conversion is performed by the compiler, and manual conversion is performed by the developer. Type casting for primitives and classes is somewhat different, so we will consider them separately. Primitive types An example of automatic casting of primitive types:
int value = 17;
double convertedValue = value;
As you can see, no additional manipulations other than the = sign are needed here. Example of manual casting of primitive types:
double value = 17.89;
int convertedValue = (int)value;
In this case, we can observe a manual cast, which is implemented using (int) , whereby the part after the comma will be discarded and the convertedValue will have a value of - 17. Read more about casting primitive types in this article . Well, now let's move on to objects. Reference types For reference types, automatic casting is possible for descendant classes to parent classes. This is also called polymorphism . Let's say we have a Lion class that inherits from a Cat class . In this case, the automatic conversion will look like this:
Cat cat = new Lion();
But with an explicit cast , everything is somewhat more complicated, because there is no functionality for cutting off excess, like with primitives. And just doing an explicit conversion of the form:
Lion lion= (Lion)new Cat();
You will get an error: Analysis of questions and answers from interviews for Java developer.  Part 16 - 8In fact, you can add methods to the Lion descendant class that were not originally in the Cat class , and then try to call them, because your object type will become Lion . Well, there is no logic in this. Therefore, type narrowing is only possible when the original object was of type Lion but was later cast to a parent class:
Lion lion = new Lion();
Cat cat = lion;
Lion newLion = (Lion)cat;
Also, for greater reliability, a narrowing cast for objects is recommended using the instanceOf construct :
if (cat instanceof Lion) {
 newLion = (Lion)new Cat();
}
Read more about reference type casts in this article .

21. Why do modern frameworks mainly use only unchecked exceptions?

I think this is all because handling checked exceptions is still spaghetti code that is repeated everywhere, but is not really needed in all cases. Analysis of questions and answers from interviews for Java developer.  Part 16 - 9In such cases, it is easier to do the processing inside the framework, so as not to once again shift this onto the shoulders of the developers. Yes, of course, an emergency situation may arise, but these same unchecked exceptions can be handled in a more convenient way, without bothering with processing in try-catch and without passing them further through methods. It is enough just to convert the exception into some HTTP response in exceptionHandler .

22. What is static import?

When using static data (methods, variables), you can not create the object itself, but do it by the name of the class, but even in this case we need a reference to the class. Everything is simple with it: it is added using regular import. But what if we go to use a static method without writing the class name, as if it were a static method of the current class? This is possible with static import! In this case, we must write static import and a link to that method. Like this, for example, a static method of the Math class for calculating the cosine value:
import static java.lang.Math.cos;
As a result, we can use the method without specifying the class name:
double result = cos(60);
We can also simply load all the static methods of a class at once using static import:
import static java.lang.Math.*;
Analysis of questions and answers from interviews for Java developer.  Part 16 - 10

23. What is the relationship between hashCode() and equals() methods?

According to Oracle , the rule is: If two objects are equal (i.e. the equals() method returns true ), they must have the same hash code. At the same time, do not forget that two different objects can have the same hash code. To understand why equals() and hashCode() are always overridden in pairs, consider the following cases:
  1. Both methods are overridden.

    In this case, two different objects with the same internal states will return equals() - true , while hashCode() will both return the same number.

    It turns out that everything is okay, because the rule is being followed.

  2. Both methods are not overridden.

    In this case, two different objects with the same internal states will return false when equals() , since the comparison is by reference through the == operator .

    The hashCode() method will also return different values ​​(most likely) since it produces the converted value of the memory location address. But for the same object this value will be the same, just as equals() in this case will return true only when the references point to the same object.

    It turns out that in this case everything is ok and the rule is fulfilled.

  3. Overridden equals() , not overridden hashCode() .

    In this case, for two different objects with the same internal states, equals() will return true , and hashCode() will return (most likely) different values.

    This is a violation of the rule, so it is not recommended to do this.

  4. equals() is not overridden , hashCode() is overridden .

    In this case, for two different objects with the same internal states, equals() will return false and hashCode() will return the same values.

    There is a violation of the rule, so the approach is incorrect.

As you can see, the rule can only be executed when equals() and hashCode() are both overridden or both are not overridden at all. Read Analysis of questions and answers from interviews for Java developer.  Part 16 - 11more about equals() and hashCode() in this article .

24. When are the BufferedInputStream and BufferedOutputStream classes used?

InputStream is used to read data byte-by-byte from some resource, and OutputStream is used to write data byte-byte. But byte-by-byte operations can be very inconvenient and require additional processing (in order to read/write texts normally). Actually, to simplify such byte records, BufferedOutputStream was introduced , and BufferedInputStream was introduced for reading . These classes are nothing more than buffers that accumulate data, allowing you to work with data not byte by byte, but by entire data packets (arrays). When created, BufferedInputStream takes into its constructor an instance of the InputStream type , from which data is read:
BufferedInputStream bufferedInputStream = new BufferedInputStream(System.in);
byte[] arr = new byte[100];
bufferedInputStream.read(arr);
System.in is an InputStream object that reads data from the console. That is, using this BufferedInputStream object , we can read data from the InputStream by writing it to the passed array. This turns out to be a kind of wrapper of the InputStream class . The arr array from this example is the array that receives data from BufferedInputStream . That, in turn, reads data from the InputStream with another array, which by default has a size of 2048 bytes. The same is true for BufferedOutputStream : an instance of the OutputStream type must be passed to the constructor , into which we will write data in entire arrays:
byte[] arr = "Hello world!!!".getBytes();
BufferedOutputStream bufferedInputStream = new BufferedOutputStream(System.out);
bufferedInputStream.write(arr);
bufferedInputStream.flush();
System.out is an OutputStream object that writes data to the console. The flush() method sends data from the BufferedOutputStream to the OutputStream , flushing the BufferedOutputStream in the process . Without this method, nothing will be recorded. And similar to the previous example: arr is the array from which data is written to the BufferedOutputStream . From there they are written to OutputStream in a different array, which by default has a size of 512 bytes. Read more about these two classes in the article .

25. What is the difference between the java.util.Collection and java.util.Collections classes?

Collection is an interface that is the head of the collection hierarchy. It introduces classes that allow you to create, contain, and modify entire groups of objects. There are many methods provided for this, like add() , remove() , contains() and others. Main interfaces of the Collection class :
  • Set is an interface that describes a set that contains unordered unique (non-repeating) elements.

  • List is an interface that describes a data structure that stores an ordered sequence of objects. These objects receive their own index (number), using which you can interact with them: take, delete, change, overwrite.

  • Queue is an interface that describes a data structure with storing elements in the form of a queue that follows the rule - FIFO - First In First Out .

Analysis of questions and answers from interviews for Java developer.  Part 16 - 12Read more about Collection . Collections is a utility class that provides many different utility methods. For example:
  • addAll(Collection<? super T> collection, T...element) - adds the passed elements of type T to the collection .

  • copy(List<? super T> dest, List<? extends T> src) - copies all elements from the list src to the list in dest .

  • emptyList() - returns an empty list.

  • max(Collection<? extends T> collection, Comparator<? super T> comp) - Returns the maximum element of a given collection according to the order specified by the specified comparator.

  • unmodifiableList(List<? extends T> list) - returns an unmodifiable representation of the passed list.

And there are a great many such various convenient methods in Collections . Analysis of questions and answers from interviews for Java developer.  Part 16 - 13A complete list of these methods can be found on the Oracle website . It’s not for nothing that I said that they are comfortable. After all, they are all static. That is, you do not need to create an object of this class every time in order to call the necessary method on it. You just need to enter the name of the class, call the desired method on it and pass all the required arguments. To summarize, Collection is the root interface of the collections framework. Collections is a helper class for more convenient processing of objects belonging to a type from the collections structure. Well, that's all for today. All the best!Analysis of questions and answers from interviews for Java developer.  Part 16 - 14
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION