[Android -- Interview] Collection of Android Interview Questions (Java Basics)

insert image description here

Java basics

1. Java class loading process

The process of jvm loading .class class file information into memory and parsing it into corresponding class objects,

Note: jvm does not load all classes into memory at the beginning, it only loads when it encounters a class that needs to be run for the first time, and only loads it once

It is mainly divided into three parts: 1. Loading, 2. Linking (1. Verification, 2. Preparation, 3. Analysis), 3. Initialization

  • Loading
    class loaders include BootClassLoader, ExtClassLoader,APPClassLoader

  • Link

    • Verification: (verify whether the byte stream of the class file conforms to the jvm specification)
    • Preparation: allocate memory for class variables and assign initial values
    • Parsing: The process of replacing symbolic references (variable names) in the constant pool with direct references (memory addresses). In the parsing phase, jvm will replace all class names, method names, field names, and these symbolic references with specific memory addresses. or offset.
  • Initialization
    mainly initializes class variables and executes the process of class constructors, in other words, only initializes static variables or statements.
    Example: Person person = new Person();Explain as an example.

The initialization process of classes in Java programming thinking mainly has the following points:

  • Find the class file and load it into memory
  • Allocate memory address in heap memory
  • initialization
  • Point the heap memory address to the p variable in the stack memory

2、String、StringBuilder、StringBuffer

Many methods in StringBuffer have added the synchronized keyword, which can represent thread safety, so use it in multi-threaded situations.

Execution speed:

StringBuilder > StringBuffer > String

StringBuilder sacrifices performance for speed. These two can be modified directly on the original object, eliminating the process of creating new objects and recycling old objects. String is a string constant (final), and the other two are String variables, constant objects cannot be modified once they are created, but variables can be modified, so the operation of String strings includes the following three steps:

  1. Create a new object with the same name as the original
  2. make changes on the new object
  3. The original object is garbage collected

3. JVM memory structure

During the instantiation of Java objects, the virtual machine stack, Java heap and method area are mainly used. After the Java file is compiled, it will first be loaded into the jvm method area. A very important part of the jvm method area is the runtime constant pool, which is used to store the version, field, method, interface and other description information of the class file class and compile period. constants and static constants.

3.1 Basic structure of JVM
The class loader, classLoader, loads the required .class files into the memory when the JVM starts or when the class is running. The execution engine is responsible for executing the bytecode instructions contained in the class file. The local method interface is mainly to call the local method implemented by C/C++ and return the result. The memory area (runtime data area) is the memory area allocated by the operation when the JVM is running. It is mainly divided into the following five parts, as shown in the figure below:
insert image description here

  • Method area : the place used to store class structure information, including constant pools, static variables, constructors, etc.
  • Java heap (heap) : The place where Java instances or objects are stored. This is the main area of ​​gc.
  • Java stack (stack) : The Java stack is always associated with a thread. Whenever a thread is created, the JVM will create a corresponding Java stack for the thread. In this java stack, multiple stack frames will be included. Every time a method is run, a stack frame is created to store local variable tables, operation stacks, and method return values. The process of each method from invocation to execution completion corresponds to the process of a stack frame being pushed into the java stack to popped out of the stack. So the java stack is private to the thread.
  • Program counter : It is used to save the memory address of the current thread execution. Since the JVM is executed by multiple threads, in order to ensure that the thread can be restored to the original state after switching back, an independent counter is needed to record the previously interrupted place, which can be seen in the program Counters are also thread-private.
  • Native method stack : It is similar to the Java stack, but it serves the native method used by the JVM.

3.2 JVM source code analysis

4. GC mechanism

The garbage collector generally does two things:

  • garbage detected;
  • recycle garbage;

4.1 Java object references
Generally, Java object references can be divided into four categories: strong references, soft references, weak references, and phantom references.

  • Strong reference : Generally, it can be considered as an object created through new. Even if the memory is insufficient, the GC will not actively recycle it when it collects garbage.
Object obj = new Object();
  • Soft reference : When the memory is insufficient, the GC will be reclaimed by the GC when it collects garbage.
Object obj = new Object();
SoftReference<Object> softReference = new SoftReference<>(obj);
  • Weak reference : Regardless of whether the memory is sufficient or not, the GC will recycle when it performs garbage collection.
Object obj = new Object();
WeakReference<Object> weakReference = new WeakReference<>(obj);
  • Phantom references : Similar to weak references, the main difference is that phantom references must be used with reference queues.
Object obj = new Object();
ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
PhantomReference<Object> phantomReference = new PhantomReference<>(obj, referenceQueue);
  • Reference queue : If soft references and weak references are recycled by GC, JVM will add this reference to the reference queue. If it is a virtual reference, it will be added to the reference queue before recycling.

Garbage detection method :

  • Reference counting method : Add a reference counter to each object, and every place refers to it, the counter will be +1, and -1 when it fails. If two objects refer to each other, they cannot be recycled.
  • Reachability analysis algorithm : Search with the root set object as the starting point. If the object is unreachable, it is a garbage object. Root set (objects referenced in the Java stack, objects referenced in the constant pool in the method area, objects referenced in local methods, etc. When the JVM is garbage collected, it will check whether all objects in the heap are referenced by these root set objects. Objects that can be referenced will be reclaimed by the garbage collector.)

Garbage collection algorithm:

  • Mark-clear
    mark : first mark all the objects that need to be recycled, and collect all marked objects after the marking is completed. Its marking process is the above reachability analysis algorithm.
    Cleanup : Clear all marked objects
    Disadvantages : Insufficient efficiency, marking and clearing efficiency is not high
    Space problem, a large number of discontinuous memory fragments will be generated after marking and clearing, resulting in the failure to find enough space for large object allocation, and garbage collection in advance.

  • The copy recovery algorithm
    divides the available memory into 2 blocks of equal size according to the capacity, and only one block is used at a time. When the memory of this block is used up, the surviving objects are copied to another block, and then the used memory space is Clean it up all at once.
    Disadvantages :
    The memory is reduced to the original size, and the cost is relatively high.
    Most of the objects are "life and death", so it is not necessary to divide them according to the ratio of 1:1.
    Now commercial virtual machines use this algorithm to reclaim the new generation, but instead of using a 1:1 ratio, the memory area is divided into three parts: eden space, from space, and to space.
    Among them, from space and to space can be regarded as two space blocks with the same size, equal status and interchangeable roles for replication. The from and to spaces are also called survivor spaces, that is, survivor spaces, which are used to store objects that have not been recycled.
    During garbage collection, the surviving objects in the eden space will be copied to the unused survivor space (assumed to), and the young objects in the survivor space in use (assumed to be from) will also be copied to the to space ( Large objects, or old objects will directly enter the old age zone, if the to space is full, the object will also directly enter the old age). At this time, the remaining objects in the eden space and the from space are garbage objects, which can be emptied directly, and the to space stores the surviving objects after recycling. This improved copy algorithm not only ensures the continuity of space, but also avoids a lot of waste of memory space.

  • Mark-organize
    Most of the objects in the old generation are surviving objects, and the replication algorithm will become less efficient when the object survival rate is high. According to the characteristics of the old generation, someone proposed the "mark-compression algorithm (Mark-Compact)" The
    marking process is the same as the mark-clear mark, but the follow-up is not to clean up the recyclable objects, but to move all the objects to one end , and then directly clean up the memory outside the end boundary.
    This method not only avoids the generation of fragments, but also does not require two identical memory spaces, so its cost performance is relatively high.

  • Banded collection algorithm
    Divide the memory into several blocks according to the life cycle of the object. Generally, the Java heap is divided into the old generation and the new generation, so that an appropriate collection algorithm is adopted according to the characteristics of each age.
    A large number of objects die every time the new generation is collected, and only a small number survive, so the replication algorithm is used, and the collection can be completed with a small number of objects copied.
    The survival rate of objects in the old age is high, and the mark-compression algorithm is used to improve the efficiency of garbage collection.

5. Class loader

When the program starts, it does not load all the class files used by the program at one time, but dynamically loads a certain class file into the memory through Java's class loading mechanism (ClassLoader) according to the needs of the program, so that only After the class file is loaded into memory, it can be referenced by other classes. So ClassLoader is used to dynamically load class files into memory.

5.1 The principle of parental delegation
Each ClassLoader instance has a reference to the parent class loader (not an inheritance relationship, but an inclusion relationship). The built-in virtual machine class loader (Bootstrap ClassLoader) itself does not have a parent class loader, but it can be used Be the parent class loader for other ClassLoader instances.
When a ClassLoader instance needs to load a class, it attempts to delegate this task to its parent class loader before searching for the class itself. This process is checked from top to bottom, and the top-level class is loaded first. Bootstrap CLassLoaderIf it is not loaded, it will transfer the task to the view to Extension CLassLoaderload. If it is not found, it will be transferred to the AppCLassLoaderloader. If it is still not found, it will be transferred to the initiator of the delegation, and it will go to the specified file system or network. URL to load classes. If not found, CLassNotFoundExceptionan exception will be thrown. Otherwise, generate a class definition for this class, load it into memory, and finally return the Class instance object of this class in memory.

5.2 Why use the parent delegation model
When judging whether two classes are the same, the JVM not only needs to judge whether the two class names are the same, but also judges whether they are loaded by the same class loader.
Avoid repeated loading. The parent class has already been loaded, so the child CLassLoader does not need to load again.
Considering the security factor, suppose you customize a String class, unless you change the default algorithm of the search class of CLassLoader in JDK, otherwise the user-defined CLassLoader loads a String class written by yourself, because the String class is loaded by the boot class at startup Bootstrap CLassLoader loaded.

6. Collection

The Java collection class is mainly derived from two interfaces: Collection and Map, which are the root interfaces of the Java collection.

The Collection interface is the root interface of the collection class, and there is no direct implementation class for this interface in Java. But let it be inherited to generate two interfaces, namely Set and List. Set cannot contain duplicate elements. List is an ordered collection that can contain repeated elements and provides access by index.

Map is another interface in the Java.util package. It has nothing to do with the Collection interface and is independent of each other, but they all belong to the collection class. Map contains key-value pairs. Map cannot contain duplicate keys, but it can contain the same value.

6.1 The difference between
List and Set is inherited from the Collection interface, while Map is not;
List features: elements have an order of placement, and elements can be repeated; Set features: elements have no order of placement, elements cannot be repeated, and repeated elements will be overwritten, (note : Although the elements are not placed in order, the position of the element in the set is determined by the HashCode of the element, and its position is actually fixed. Objects added to the Set must define the equals() method; LinkedList, ArrayList, and HashSet are not thread-
safe Yes, Vector is thread-safe;
HashMap is non-thread-safe, and HashTable is thread-safe;

6.2. Comparison between List and Vector
Vector is multi-thread safe. Thread safety means that multi-thread access to the same code will not produce uncertain results. But ArrayList is not. This can be seen from the source code. Many methods in the Vector class are modified by synchronized, which leads to the fact that Vector cannot compare with ArrayList in terms of efficiency; both use
linear continuous space to store elements, but When the space is insufficient, the two classes increase in different ways.
Vector can set the growth factor, but ArrayList cannot.
Vector is an old dynamic array, which is thread-synchronized, and the efficiency is very low, so it is generally not recommended to use.

6.3. How to ensure that HashSet does not repeat
HashSet. The bottom layer of HashSet is realized by HashMap. Adding elements to HashSet is

public boolean add(E e) {
    
    
return map.put(e, PRESENT)==null;
}


// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();

In the HashMap to find out whether the key exists, the value is always the same, mainly in the following situations:

  • If the hash code values ​​are different, it means it is a new element, save it;
  • If the hash code values ​​are the same, and the equals judgment is equal, it means that the element already exists and does not exist;
  • If the hash code values ​​are the same, and the equals judgment is not equal, it means that the element does not exist, save;
  • If any element is equal to the hash value of the incoming object, then proceed to the equles() judgment. If it is still equal, then the incoming element is considered to exist, no longer added, end, otherwise still added;

6.4 Applicable scenarios of HashSet and Treeset

  • HashSet is implemented based on the Hash algorithm, and its performance is usually better than that of TreeSet. For Set designed for fast lookup, we should usually use HashSet, and we only use TreeSet when we need sorting functions.
  • TreeSet is implemented by a binary tree (the tree data structure of a red-black tree), and the data in the Treeset is automatically sorted, and null values ​​are not allowed
  • HashSet is implemented by hash table. The data in HashSet is unordered, and null can be placed, but only one null can be placed. The values ​​in both cannot be repeated, just like the unique constraint in the database.
  • HashSet is implemented based on the Hash algorithm, and its performance is usually better than that of TreeSet. For Sets designed for fast lookups, we should usually use HashSets, and we only use TreeSets when we need sorting functions.

6.5 Differences between HashMap, TreeMap, and HashTable and applicable scenarios
HashMap is not thread-safe and is implemented based on a hash table (hash table). The key class required to use HashMap clearly defines hashCode() and equals() [hashCode() and equals() can be overridden]. In order to optimize the use of HashMap space, you can tune the initial capacity and load factor. There are mainly two types of conflict handling for hash tables, one is the open addressing method, and the other is the linked list method. The linked list method is used in the implementation of HashMap.
TreeMap: non-thread-safe implementation based on red-black tree, TreeMap has no tuning options, because the tree is always in a balanced state

7. Constant pool

7.1 128 (-128~127) in Integer
When the value range is -128~127: If two new Integer objects come out, even if the values ​​are the same, the comparison result of "==" is false, but the two objects are directly assigned, Then the result of "==" comparison is "true", which is very similar to String. When the value is not between -128~127, no matter which method is used, even if the values ​​​​of the two objects are equal, through "== " comparison, its The result is false; when an Integer object is directly compared with an int basic data type by "==", the result is the same as the first point; the hash value of the Integer object is the value itself;

@Override
public int hashCode() {
    
    
return Integer.hashCode(value);
}

7.2 Why is it -128 ~ 127?
There is a static internal class IntegerCache in the Integer class, and there is an Integer array in the IntegerCache class to cache Integer objects when the value range is -128~127.

8. Generics

Generics are a new feature of Java SE 1.5. The essence of generics is a parameterized type, which means that the type of data being manipulated is specified as a parameter. This parameter type can be used in the creation of classes, interfaces, and methods, and is called generic classes, generic interfaces, and generic methods, respectively. The advantage of introducing generics in the Java language is that it is safe and simple.

The advantage of generics is that type safety is checked at compile time, and all casts are automatic and implicit, which improves code reuse.

It provides compile-time type safety, ensuring that you can only put objects of the correct type into the collection, avoiding them at runtime ClassCastException.

When using Java's generics, you should pay attention to the following points:

  • Generic type parameters can only be class types (including custom classes), not simple types.
  • The same generic type can correspond to multiple versions (because the parameter type is uncertain), and the generic class instances of different versions are incompatible.
  • A generic type parameter can have more than one.
  • Generic parameter types can use the extends statement, eg. It is customary to call it a "bounded type".
  • Generic parameter types can also be wildcard types. For exampleClass<?> classType = Class.forName("java.lang.String");

8.1 T generics and wildcard generics

  • ? Represents an indeterminate java type.
  • T represents the java type.
  • KV respectively represent the Key Value in the java key value.
  • E stands for Element.

8.2 Generic erasure
Generics in Java are basically implemented at the compiler level. The type information in generics is not included in the generated Java bytecode. The type parameters added when using generics will be removed when the compiler compiles. This process is called type erasure.

Generics are implemented through type erasure. The compiler erases all type-related information at compile time, so there is no type-related information at runtime. For example, List is represented by only one List at runtime. The purpose of this is to ensure compatibility with the development of binary class libraries prior to Java 5. You can't access the type parameters at runtime because the compiler has converted the generic type to a primitive type.

8.3 Limited wildcards
One is <? extends T> which sets the upper bound of the type by ensuring that the type must be a subclass of T,
and the other is <? super T> which sets the upper bound of the type by ensuring that the type must be the superclass of T The lower bound of the given type.
On the other hand, unqualified wildcards are represented, since any type can be substituted.
For example List<? extends Number> can accept List or List.

8.4 Generic Interview Questions
Can you pass a List to a method that accepts a List parameter?

For anyone who is not familiar with generics, this topic of Java Generics may seem confusing, because at first glance String is a kind of Object, so List should be used
where List is expected, but it is not. Doing so will cause compilation errors. If
you think about it further, you will find that it makes sense for Java to do this, because List can store any type of object including String,
Integer, etc., but List can only be used to store Strings.

Can generics be used in Array?

Array does not actually support generics, which is why Joshua Bloch
suggested using List instead of Array in the book Effective Java, because List can provide compile-time type safety guarantees, but Array cannot.

9. Reflection

9.1 Concept

The JAVA reflection mechanism is in the running state. For any class, you can know all the properties and methods of this class; for any object, you can call any of its methods; The function of the method is called the reflection mechanism of the java language.

9.2 Function
The Java reflection mechanism mainly provides the following functions: Judging the class of any object at runtime; constructing an object of any class at runtime; judging the member variables and methods of any class at runtime; Call any method of an object; generate a dynamic proxy.

recommended reading

Guess you like

Origin blog.csdn.net/duoduo_11011/article/details/131322093