java - "Interview Questions - Basics"

1. What are the characteristics of the Java language

1. Easy to learn, rich class library
2. Object-oriented (the most important feature of Java, which makes the program less coupled and cohesive)
3. Platform-independent (JVM is the foundation of Java cross-platform use)
4. Reliable and safe
5. Support multi-threading

2. The difference between object-oriented and process-oriented 

Process-oriented:
It is to analyze the steps to solve the problem, and then use functions to realize these steps step by step, and then call them one by one when using them . The performance is high, so single-chip microcomputer, embedded development, etc. generally adopt process-oriented development.

Object-oriented: It is to decompose the transaction that constitutes the problem into various objects, and the purpose of establishing an object is not to complete each step,
but to describe the behavior of a certain thing in the process of solving the entire problem. Object-oriented has the characteristics of encapsulation, inheritance, and polymorphism
, so it is easy to maintain, reuse, and expand. Systems with low coupling can be designed. But in terms of performance, it is
lower than process-oriented.

3. The size of the eight basic data types and their encapsulation classes

Note:
1. Int is a basic data type, and Integer is an encapsulation class of int, which is a reference type. The default value of int is 0, and the default value of Integer is null, so Integer can distinguish between 0 and null. Once java sees null, it knows that the reference has not pointed to an object. Before any reference is used, an object must be specified for it, otherwise an error will be reported.

2. The system will automatically allocate space for the basic data type when it is declared, while the reference type is only allocated a reference space when it is declared, and it must be instantiated to open up the data space before it can be assigned. An array object is also a reference object. When assigning an array to another array, only a reference is copied, so the modification made through one array can also be seen in another array.

Although the boolean data type is defined, it only provides very limited support. In the Java virtual machine, there are no bytecode instructions dedicated to boolean values. The boolean values ​​​​operated by Java language expressions are replaced by the int data type in the Java virtual machine after compilation, and the boolean array will be encoded. It becomes a byte array of the Java virtual machine, and each boolean element occupies 8 bits. In this way, we can conclude that the boolean type occupies 4 bytes when used alone, and 1 byte in the array. The reason for using int is that for the current 32-bit processor (CPU), the data processed at a time is 32 bits (this does not refer to the 32/64-bit system, but to the CPU hardware level), which has efficient access features.

4. Naming rules for identifiers

The meaning of the identifier:
refers to the content that we define ourselves in the program, such as the name of the class, method name and variable name, etc., are all identifiers.
Naming rules: (Mandatory requirement)
Identifiers can contain English letters, numbers from 0-9, $ and _ Identifiers cannot start with numbers. Identifiers are not keywords.
Naming convention: (non-hard requirement)
Class name convention: capitalize the first character, and capitalize the first letter of each following word (big camel case).
Variable name specification: the first letter is lowercase, and the first letter of each subsequent word is capitalized (small camel case).
Method name specification: Same as variable name.

5. The role of the instanceof keyword

Strictly speaking, instanceof is a binary operator in Java, which is used to test whether an object is an instance of a class. The usage is:

boolean result = obj instanceof Class

Where obj is an object, and Class represents a class or an interface. When obj is an object of Class, or its direct
or indirect subclass, or the implementation class of its interface, the result returns true, otherwise it returns false.

Note: The compiler will check whether obj can be converted into the class type on the right. If it cannot be converted, an error will be reported directly. If the
type cannot be determined, it will be compiled, depending on the runtime.

int i = 0;
System.out.println(i instanceof Integer);//编译不通过 i必须是引用类型,不能是基本类型
System.out.println(i instanceof Object);//编译不通过
Integer integer = new Integer(1);
System.out.println(integer instanceof Integer);//true
//false ,在 JavaSE规范 中对 instanceof 运算符的规定就是:如果 obj 为 null,那么将返回 false。
System.out.println(null instanceof Object);

6. Java automatic boxing and unboxing

Boxing is to automatically convert the basic data type into a wrapper type (int-->Integer); calling method:
valueOf(int) method of Integer

Unboxing is to automatically convert the wrapper type to the basic data type (Integer-->int). Call method:
IntValue method of Integer

Before Java SE5, if you want to generate an Integer object with a value of 10, you must do this:

Integer i = new Integer(10);

 Since Java SE5 has provided the feature of autoboxing, if you want to generate an Integer object with a value of 10, you only need to do
this:

Integer i = 10;

 Interview question 1: What will the following code output?

public class Main {
    public static void main(String[] args) {
 
    Integer i1 = 100;
    Integer i2 = 100;
    Integer i3 = 200;
    Integer i4 = 200;
 
    System.out.println(i1==i2);
    System.out.println(i3==i4);
    }
}

operation result:

true
false

Why is there such a result? The output shows that i1 and i2 point to the same object, while i3 and i4 point to different objects
. At this point, you only need to look at the source code to know the truth. The following code is the specific implementation of the valueOf method of Integer: 

public static Integer valueOf(int i) {
    if(i >= -128 && i <= IntegerCache.high)
        return IntegerCache.cache[i + 128];
    else
        return new Integer(i);
}
The implementation of the IntegerCache class is:
private static class IntegerCache {
    static final int high;
    static final Integer cache[];
    static {
        final int low = -128;
        // high value may be configured by property
        int h = 127;
        if (integerCacheHighPropValue != null) {
            // Use Long.decode here to avoid invoking methods that
            // require Integer's autoboxing cache to be initialized
            int i = Long.decode(integerCacheHighPropValue).intValue();
            i = Math.max(i, 127);
            // Maximum array size is Integer.MAX_VALUE
            h = Math.min(i, Integer.MAX_VALUE - -low);
        }
        high = h;
        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);
    }
    private IntegerCache() {}
}

As can be seen from these two pieces of code, when an Integer object is created by the valueOf method, if the value is between [-128,127], a
reference to an object that already exists in IntegerCache.cache is returned; otherwise, a new Integer object is created .

In the above code, the values ​​of i1 and i2 are 100, so the existing objects will be fetched directly from the cache, so i1 and i2 point to the
same object, while i3 and i4 point to different objects respectively.

Interview Question 2: What does the following code output

public class Main {
    public static void main(String[] args) {
 
    Double i1 = 100.0;
    Double i2 = 100.0;
    Double i3 = 200.0;
    Double i4 = 200.0;
 
    System.out.println(i1==i2);
    System.out.println(i3==i4);
    }
}

operation result:

false
false

Reason: The number of integer values ​​in a certain range is limited, but floating point numbers are not.

7. The difference between overloading and rewriting

Override

Literally, rewriting means rewriting it all over again. In fact, it is to rewrite the methods of the parent class itself in the subclass. The subclass inherits the original method of the parent class, but sometimes the subclass does not want to inherit a method in the parent class intact, so in the method name, parameter list, return type (except the return value of the method in the subclass When it is a subclass of the return value of the method in the parent class), modifying or rewriting the method body is called rewriting. However, it should be noted that the access modification permissions of subclass functions cannot be less than those of the parent class.

public class Father {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Son s = new Son();
        s.sayHello();
    }
    public void sayHello() {
        System.out.println("Hello");
    }
}

class Son extends Father{
    @Override
    public void sayHello() {
        // TODO Auto-generated method stub
        System.out.println("hello by ");
    }
}

Rewriting summary:
 1. Occurs between the parent class and the subclass 
2. The method name, parameter list, and return type (except that the return type of the method in the subclass is the subclass of the return type in the parent class) must be the same 3. 
Access The restriction of the modifier must be greater than the access modifier of the overridden method (public>protected>default>private) 
4. The overridden method must not throw new checked exceptions or checked exceptions that are wider than the overridden method declaration

Overload

In a class, methods with the same name are considered overloaded if they have different parameter lists ( different parameter types, different numbers of parameters, or even different order of parameters
)
. At the same time, overloading has no requirement on the return type, which can be the same or different, but
the overloading cannot be judged by whether the return types are the same
.

public class Father {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Father s = new Father();
        s.sayHello();
        s.sayHello("wintershii");
    }
    public void sayHello() {
        System.out.println("Hello");
    }
    public void sayHello(String name) {
        System.out.println("Hello" + " " + name);
    }
}

Summary of overloading: 
1. Overloading Overload is a manifestation of polymorphism in a class 
2. Overloading requires different parameter lists for methods with the same name (parameter type, number of parameters and even parameter order) 
3. When overloading, The return type can be the same or different. The return type cannot be used as the criterion for distinguishing overloaded functions

8. The difference between equals and ==

== :

== compares the (heap) memory address of the object stored in the variable (stack) memory, and is used to judge whether the addresses of the two objects are the same, that is, whether they refer to the same
object. The comparison is a pointer operation in the true sense.

1. The comparison is whether the operands at both ends of the operator are the same object. 
2. The operands on both sides must be of the same type (can be between parent and child classes) to pass the compilation. 
3. The comparison is the address. If it is a comparison of specific Arabic numerals, the value is equal to true, such as: int a=10 and long b=10L and double c=10.0 are the same (true), because they are both Points to the heap at address 10.

equals:

equals is used to compare whether the contents of two objects are equal. Since all classes are inherited from the java.lang.Object class,
it applicable to all objects. If the method is not overridden, the call is still The method in the Object class, and
the equals method in Object returns the judgment of ==.

Summary:
When all comparisons are equal, use equals and when comparing constants, write the constants first, because the
equals object using the object may be null or a null pointer.
Only use equals in Ali's code specification, and Ali The plug-in will be recognized by default and can be quickly modified. It is recommended to install the Ali plug-in to check the old code. Use "==" and replace it with equals

9. The function of Hashcode

There are two types of collections in java, one is List and the other is Set. forward

The ones are ordered and repeatable, and the latter are disordered and non-repetitive. How to judge whether the element already exists when we insert it in the set, we can use the equals method. But if there are too many elements, using this method will be slower.

So someone invented the hash algorithm to improve the efficiency of finding elements in the collection. This method divides the collection into several storage areas. Each object can calculate a hash code, and the hash codes can be grouped. Each group corresponds to a storage area. The object can be determined according to the hash code of an object. The area where it should be stored.

The hashCode method can be understood in this way: what it returns is a value converted according to the memory address of the object. In this way, when a new element is to be added to the collection, the hashCode method of this element is called first, and the physical location where it should be placed can be located at once. If there is no element at this position, it can be directly stored at this position without any comparison; if there is already an element at this position, call its equals method to compare with the new element, and if it is the same, it will not be stored If it is not the same, hash other addresses. In this way, the number of actual calls to the equals method is greatly reduced, almost only one or two times.

10. What is the difference between String, String StringBuffer and StringBuilder?

String is a read-only string, it is not a basic data type, but an object. From the perspective of the underlying source code, it is a final character array. The referenced string cannot be changed. Once defined, it cannot be added, deleted or modified. Each operation on String will generate a new String object.

private final char value[];

Each + operation: Implicitly create a new StringBuilder object on the heap that is the same as the original string, and then call the append method to concatenate + the following characters.

Both StringBuffer and StringBuilder inherit the AbstractStringBuilder abstract class. We can see from the AbstractStringBuilder abstract class

/**
* The value is used for character storage.
*/
char[] value;
Their underlying layers are variable character arrays, so when performing frequent string operations, it is recommended to use StringBuffer and
StringBuilder for operations. In addition, StringBuffer adds a synchronization lock to the method or a synchronization lock to the method being called, so it is thread-safe. StringBuilder does not add a synchronization lock to the method, so it is not thread-safe.

 

Guess you like

Origin blog.csdn.net/weixin_43042683/article/details/130231196