Android development interview: Java knowledge answer fine explanation

Table of contents

Java

gather

collection overview

HashMap

ConcurrentHashMap

generic

reflection

annotation

I流

Exception, shallow copy and new features of Java8

java exception

deep copy

Java8 new features

concurrency

thread

Thread Pool

Lock

volatile

JVM

memory area

memory model

class loading mechanism

garbage collection mechanism

How to tell if an object is dead


Java

gather

collection overview

  1. Collection classification: roughly divided into four systems: List, Set, Map and Queue (Set represents an unordered and non-repeatable collection, List represents an ordered and repeated collection, Map represents a collection with a mapping relationship, and Queue represents a queue collection accomplish)
  2. The difference between a collection and an array: a. Length: The length of an array is specified at initialization, while a collection can store an indeterminate amount of data, and at the same time can store data with a mapping relationship; b. Element type: an array element can be a value of a basic type, It can also be an object, but only objects can be saved in the collection (in fact, only the reference variable of the object is saved), and the basic data type must be converted into the corresponding wrapper class before it can be put into the collection class
  3. Collection class relationship: Collection and Map are the root interfaces of the Java collection framework, List (the List collection adds some methods for manipulating collection elements according to the index), Set (the Set collection is basically the same as the Collection collection, and does not provide any additional methods, actually The above Set is Collection, but Set does not allow to contain duplicate elements) and Queue (Queue simulates the "first in, first out" data structure of the queue, usually the queue does not allow random access to the elements in the queue) interface inherits from Collection, and all keys in the Map are equivalent to A Set collection, all values ​​are equivalent to a List collection
  4. ArrayList and LinkedList: ArrayList is implemented as an array, and the query is fast, adding and deleting is slow (automatic expansion, dynamic array saves space, but the array has a capacity limit, by default, an array with a size of 10 is created when an element is inserted for the first time, and the capacity will be increased by 50% when the limit is exceeded. , use System.arraycopy() to copy to a new array, so it is best to give an estimate of the size of the array); LinkedList is implemented as a doubly linked list, and the node function changes the node access complexity from O(n) to O(n /2) (The linked list has no capacity limit, but the doubly linked list itself uses more space and requires additional linked list pointer operations)

HashMap

  1. Core: array (hash table) + linked list/red-black tree, implemented based on Map interface, allows null key/value, asynchronous, does not guarantee order (such as the order of insertion), and does not guarantee that the order will not change over time
  2. Capacity and load factor: capacity (Capacity, container size, default 16), load factor (loadFactor, maximum proportion of container fullness, default 0.75); when the number of container contents is greater than capacity*loadFactory, you need to adjust the container size to 16 2 times of
  3. Why expansion, and it is a multiple of 2: the data structure is an array that needs to be expanded; if it is a multiple of 2, bit operations can be used instead of the remainder operation, which is more efficient (when HashMap is accessed, the calculation index is (length- 1) & hash , using the & operator is more efficient than %, if the length is a multiple of 2, it can ensure that the index is evenly divided)
  4. put function: a. First hash the hashCode() of the key, and then calculate the index; b. If there is no collision, put it directly into the bucket; c. If there is a collision, there will be buckets in the form of a linked list; d. If the collision results in a linked list If it is too long (greater than or equal to 8), the linked list will be converted into a red-black tree (increasing the traversal query). When the number of nodes on the red-black tree is less than 6, the red-black tree will be changed into a one-way linked list data structure again; e, if the node If it already exists, replace the old value (to ensure the uniqueness of the key); f, if the bucket is full (more than load factor*current capacity), it must be resized
  5. get function: a. hit the first node in the bucket directly; b. if there is a conflict, use key.equals(k) to find the corresponding entry; c. if it is a tree, use key.equals in the tree (k) lookup, O(logn); if it is a linked list, search through key.equals(k) in the linked list, O(n)
  6. Hash function: a. In the process of get and put, when calculating the subscript, first perform the hash() operation on the hashCode, and then further calculate the subscript (n-1)&hash through the hash value; b. During the hash() operation The high 16 bits of hashcode() remain unchanged, and the low 16 bits and high 16 bits are XORed (when n - 1 is 15 (0x1111), in fact, only the effective bits of the low 4 bits are actually effective for the hash, which is easy to collide, so the designer started from the speed , efficiency, and quality considerations, this can be done when the n of the bucket is relatively small, and it can also ensure that both high and low bits participate in the hash calculation, and at the same time there will not be too much overhead); c, hash conflict resolution, used before Java8 Linked list O(n), red-black tree O(logn) is used in Java8 (now the distribution of most hashCode is already very good)
  7. Why does HashMap use String and int as keys: a, they are all final modified classes, which can ensure the immutability and calculation accuracy of Hash values; b, methods such as equals() and hashCode() have been rewritten internally, which can be effective Reduce Hash collisions (the hashCode of Integer is the value itself)
  8. What is the difference between HashMap and Hashtable: a. Hashtable is thread-safe, low in efficiency, and HashMap is not thread-safe (multiple threads resize at the same time may cause an infinite loop and put operation coverage), which is high in efficiency; b. null can be used as the key and value of HashMap , cannot be used as the key of Hashtable; c, Hashtable initial capacity is 11, load factor is 0.75, expansion is 2n+1; d, Hashtable has no mechanism for converting linked list to red-black tree
  9. HashMap and SpareArray: When the key is int, consider using SpareArray. SpareArray uses two arrays to store key and value. Advantages: a. There is no automatic unboxing; b. When the amount of data is not large, binary search is efficient, and there is no need to open up memory space to store additional external mappings, saving memory
  10. LinkedHashMap: array (hash table) + doubly linked list/red-black tree, doubly linked list can guarantee the access order, internally use LruCache to do the least recently used removal, inherited from HashMap (the put function is not re-implemented in LinkedHashMap, just implemented AfterNodeAccess and afterNodeInsertion two callback functions, the get function is re-implemented and added afterNodeAccess to ensure the access order)
  11. HashMap, LinkedHashMap, TreeMap: HashMap does not guarantee the order of data, LinkedHashMap guarantees the order of data insertion, and TreeMap guarantees the order of the key size of Map

ConcurrentHashMap

  1. Core: The implementation of Java8 has abandoned the Segment segment lock mechanism, and uses CAS+Synchronized to ensure the security of concurrent updates. The bottom layer still uses the storage structure of array table+linked list+red-black tree
  2. Solve the problem: HashMap multi-threaded put operation concurrent infinite loop problem; and Hashtable, Collections.synchronizedMap (hashMap) locking efficiency is low
  3. Array table initialization: it will not be initialized during construction, and will be delayed until the first put operation. The thread of the first put operation will execute the Unsafe.compareAndSwapInt method to modify sizeCtl (default 0) to -1, and only one thread can modify it Success, other threads give up the CPU time slice through Thread.yield() and wait for the table initialization to complete
  4. Array table expansion: build a nextTable twice the size of the table, and copy the table data to the nextTable
  5. put function: use CAS+synchronized to implement concurrent insert or update operations, neither key nor value can be null
  6. Get function: a. Determine whether the table is empty. If it is empty, return null directly; b. Calculate the hash value of the key, and obtain the Node node at the specified position in the specified table, and find the corresponding node by traversing the linked list or tree structure. return value

generic

  1. Generic meaning: The essence of generic is parameterized type. This type can be used in the creation of classes, interfaces and methods. It is called generic class, generic interface and generic method respectively. Boxing, variable length parameters, internal classes, etc. are also syntactic sugar)
  2. Generic benefits: Make types safer. a. Compile-time type checking, which exposes errors at compile time, without waiting until runtime, helps developers find errors more easily and improves program reliability; b. Automatic type conversion at runtime, avoiding ClassCastException in forced type conversion; c , more semantic (for example: List clearly knows that it stores String objects) and can write more generalized code (the introduction of generics does not increase the redundancy of the code)
  3. Type wildcards: upper limit (List: indicates that all elements in the collection are of the Shape type or its subclasses), lower limit (List: indicates that all elements in the collection are of the Circle type or its parent class)
  4. Generic erasure: a. Java generics are invariant (Fruit is the parent class of Apple, but List is not the parent class of List). It is type erasable and can be regarded as pseudo-generic; b. It cannot be obtained when the program is running to the specific type of an object; c. In the declaration and initialization of static methods, static initialization blocks or static variables, type parameters are not allowed; d. Since the system does not actually generate generic classes, the instanceof operator Generic classes cannot be used after

reflection

  1. Reflection mechanism: runtime, dynamically obtain class information, and dynamically call objects
  2. Reflection mechanism application scenarios: a. Reverse code (decompilation); b. Framework combined with annotations (Retrofit); c. Pure reflection mechanism application framework (EventBus); d. Dynamically generated class framework (Gson)
  3. 3 ways to get the Class object: a, Class.forName("fully qualified class name"); b, class name.class; c, object.getClass()
  4. Reflection API: a, getDeclaredFields and getFields - get all properties and get all public properties; b, getDeclaredMethods and getMethods - all methods and all public methods; c, getDeclaredConstructors and getConstructors - all construction methods and all public construction methods; d , getAnnotation(Deprecated.class)——Get the specified annotation; e, newInstance——Create an instance object; f, method.setAccessible(true) and method.invoke(obj,args)——Cancel the access check and call the corresponding method; g. field.setInt(obj,6) - set the property value of the object to 6
  5. Proxy mode: static proxy (the proxy class is implemented at compile time and is an actual class file), dynamic proxy (the class bytecode dynamically generated by the proxy class at runtime and loaded into the JVM)
  6. Dynamic proxy: It mainly involves two classes Proxy and InvocationHandler, both of which are under the java.lang.reflect package, and are mainly implemented internally through reflection
  7. Proxy: This is the main class for generating proxy classes. The proxy classes generated through the Proxy class inherit from the Proxy class and are the parent class of all dynamic proxy classes. It also provides the static method getProxyClass for creating dynamic proxy classes for users and the static method for creating proxy objects. newProxyInstance
  8. InvocationHandler: When calling the method in the dynamic proxy class, it will be directly transferred to the invoke() method in the custom InvocationHandler

annotation

  1. Metadata: is data about data, describes the data, and adds additional information to program elements such as methods, fields, classes, and packages
  2. Annotation: It is the metadata of the Java platform, which allows custom annotations to be added to Java code, and allows programmatic access to metadata through reflection
  3. Common annotations: @Override (applicable elements are methods, only reserved in Java source files), @Deprecated, @SuppressWarnings
  4. Meta-annotation: @Documented is extracted into a document, @Inherited uses @Inherited modification when a class defines @Xxx annotation, then its subclasses are automatically modified by the @Xxx annotation, @Retention (SOURCE, CLASS, RUNTIME) annotation retention time, The type of program element to which the @Target(CONSTRUCTOR, FIELD, METHOD, etc.) annotation applies
  5. When the annotation retention policy is RetentionPolicy.RUNTIME, it can be used through the reflection mechanism at runtime

I流

  1. Input and output streams: input stream (you can only read data from it, but you can't write data to it), output stream (you can only write data to it, but you can't read data from it)
  2. Byte stream and character stream: the origin of character stream - because the data encoding is different, and there is a stream object for efficient operation of characters, the essence is actually to check the specified code table when reading the byte stream. When dealing with plain text data, priority is given to using character streams, otherwise byte streams are used
  3. Node flow and processing flow: node flow (FileInputStream low-level flow, which can read/write data from/to a specific IO device (such as disk, network)), processing flow (BufferedInputStream high-level flow, wrapping node flow, through the packaged stream to implement data read/write functionality)
  4. IO stream classification: divided into the following four abstract base classes, InputStream input byte stream, OutputStream output byte stream, Reader input character stream, Writer output character stream
  5. IO stream closing: After executing the input stream operation, call the close() method to close, because the IO resource opened in the program does not belong to the memory resource, and the garbage collection mechanism cannot recycle the resource, so the file IO resource should be explicitly closed; After executing the output stream operation, call the close() method to close. Closing the output stream not only ensures that the physical resources of the stream are recovered, but also flushes the output stream buffer data into the physical node (because the close Before the () method, the flush() method of the output stream will be automatically executed
  6. RandomAccessFile advantages and disadvantages and usage scenarios: advantages (can read file content, can also output data to the file, and supports free access to any location of the file (contains a record pointer inside to achieve random access)), disadvantages (can only read and write files , cannot read and write other IO nodes), usage scenarios (multi-threaded downloads and resumed uploads in network requests)
  7. NIO: New IO, new IO can replace standard IO, and provide different working methods from standard IO. Standard IO operates based on byte stream and character stream, while NIO operates based on channel (Channel) and buffer (Buffer). Data always read from channel to buffer, or write from buffer to channel

Exception, shallow copy and new features of Java8

java exception

  1. What it is: It is a consistent mechanism for identifying and responding to errors provided by Java. The Java exception mechanism can separate the exception handling code from the normal business code in the program, ensure the program code is more elegant, and improve the robustness of the program.
  2. Keywords: try (for monitoring. Put the code to be monitored (the code that may throw an exception) in the try statement block. When an exception occurs in the try statement block, the exception will be thrown), catch (for Catch exceptions. catch is used to catch exceptions that occur in the try statement block), finally (will always be executed. Used to reclaim resources opened in the try block (such as database connections, network connections, and disk files)), throw (use used to throw exceptions), throws (used in the method signature to declare the exceptions that the method may throw)
  3. The execution order of finally and return: a. Only after the execution of the finally block is completed, the return or throw statement in the try or catch block will be executed (the finally statement is executed after the return statement is executed and before the return returns); b. If finally is used The statement of the termination method such as return or throw will not jump back to the execution and stop directly; c. If there is no return statement in the finally statement to cover the return value, then the original return value may change due to the modification in finally (change the reference) May also be unchanged (change value)
  4. Exception framework: a. Throwable is the superclass of all errors or exceptions in the Java language; b. Throwable contains two subclasses of Error and Exception; c. Among the Exception class itself and its subclasses, except for "runtime exceptions" Other subclasses belong to checked exceptions; d. RuntimeException is a subclass of Exception, and the compiler will not check runtime exceptions (the RuntimeException exception is not thrown through the throws statement, nor is it handled by try...catch... Exception", can also be compiled); e, Error is used to indicate serious problems that reasonable applications should not try to catch, and like RuntimeException, the compiler will not check Error

deep copy

  1. There are three types of object copies in Java: shallow copy (Shallow Copy), deep copy (Deep Copy), delayed copy (Lazy Copy)
  2. Shallow copy: Copying an object bitwise will create a new object that has an exact copy of the original object's attribute value (if the attribute is a basic type, the value of the basic type is copied; if the attribute is a reference type, the copy is Memory address, so if one of the objects changes this address, it will affect the other object), implementation method (the class to be copied implements the Clonable interface and rewrites the clone() method, and calls super.clone() in the method )
  3. Deep copy: all attributes will be copied, and the dynamically allocated memory pointed to by the attribute will be copied (deep copy occurs when the object and the object it refers to are copied together, and deep copy is slower and more expensive than shallow copy) , Implementation method (a, new implementation: the class that needs to be copied implements the Clonable interface and rewrites the clone() method, and a new object is created in the method (deep copy occurs only when there is a reference object in the class); b, serialization implementation)
  4. Delayed copy: It is a combination of shallow copy and deep copy. It looks like a deep copy from the outside, but it will take advantage of the speed of shallow copy as long as possible. Delayed copy can be used when the reference in the original object does not change frequently
  5. Deep and shallow copy selection: a. If the object attributes are all basic types and the object reference will not be changed at any time, shallow copy can be used; b. If the object has reference attributes, it is necessary to choose shallow copy or deep copy based on specific needs. If the object reference changes frequently, use a deep copy

Java8 new features

  1. Lambda expression and functional interface: A functional interface refers to an interface with only one function, such an interface can be implicitly converted into a Lambda expression; as long as a developer adds a function to the interface, the interface is no longer a function Type interface, which leads to compilation failure. In order to overcome this code-level vulnerability and explicitly state that an interface is a functional interface, Java8 provides a special annotation @FunctionalInterface (all related interfaces in the Java library have with this annotation)
  2. New interface features: In addition to constants and abstract methods, default methods and static methods have been added in Java8 (private methods have been added in Java9)
  3. Differences between abstract classes and interfaces in Java8: a. Inheritance: abstract classes can only be inherited single-inherited, and interfaces can be multiple-inherited by interfaces and implemented by classes; b. Different design concepts: abstract classes represent the "is-a" relationship (this object What is it), the interface represents the "like-a" relationship (what this object can do); c, variable: the variable defined in the interface is public static final by default and must be given an initial value, and cannot be redefined in the implementation class , and its value cannot be changed; the variable in the abstract class is an ordinary variable, and its value can be redefined in the subclass, or it can be reassigned

concurrency

thread

  1. There are 4 ways to create a thread: implement the Runnable interface (implement the run method, and pass it as a parameter to the Thread constructor when calling), inherit the Thread class (implement the run method), use Java8's Lambda (new Thread(()-> System.out .println(Thread.currentThread().getName())).start()), using Callable and Future (Callable and Runnable are similar, provided by JDK1.5 to make up for the situation where the calling thread has no return value)
  2. join method: thread join, description (can make parallel execution between threads into serial execution, for example: a, call thread b.join() method in thread a, then thread a will enter the blocking state until thread b executes After finishing, thread a will end the blocking state, which is also called waiting for thread b to die; b, if thread a calls thread b.join(10), then thread a will wait for thread b to execute for 10 milliseconds, and after 10 milliseconds, a and b Threads are executed in parallel), principle (join method is implemented by Object.wait method. When b.join is called in thread a, thread a will obtain the lock of thread b (wait means to get the lock of the object), and call the object of thread b wait (waiting time), until the thread b object wakes up the a thread (that is, when the thread b exits after execution)), note (because the join method will throw an exception, so try-catch is also needed to catch and handle the exception)
  3. Interrupt method: thread interruption, the function of interrupt is not to interrupt the thread, but to notify the thread that it should be interrupted. A thread should not be forced to be interrupted or stopped by other threads, but should be stopped by the thread itself        
  4. The yield method: the thread yields, giving up the time slice of the current thread CPU execution, allowing the current thread or other threads to run (it is to let itself or other threads run, not simply to give to other threads)
  5. sleep method: thread sleep, let the current thread sleep for a specified millisecond, and the current thread is blocked within the specified time
  6. The difference between sleep() and wait(): difference (sleep is a thread method, and wait is an Object method, their functions are similar), essential difference (sleep does not release the lock, wait releases the lock), and usage is different (sleep (milliseconds) can be used Time specified to make it wake up automatically, if the time is not up, you can only call interreput() to terminate the thread; wait() can be directly awakened by notify()/notifyAll())
  7. Thread synchronization: a total of synchronized (code block synchronization, method synchronization) and ReentrantLock (ReentrantLock lock = new ReentrantLock(); lock.lock();lock.unlock()) two kinds of locks to achieve thread synchronization problems, optimistic lock ReentrantLock, Pessimistic lock synchronized, Lock

Thread Pool

  1. Advantages of thread pool: a. Reduce system resource consumption (reduce the consumption caused by thread creation and destruction by reusing existing threads); b. Improve system response speed (when a task arrives, it can be executed immediately without waiting for new thread creation) ; c. Convenient thread concurrency management and control (if threads are created without limit, it will not only consume a lot of system resources, but also occupy too many resources and block the system or oom, thereby reducing system stability, and the thread pool can effectively control threads. Unified allocation, tuning, and improved resource utilization); d, more powerful functions (the thread pool provides a thread pool with functions such as timing, regularity, and controllable number of threads, which is convenient and simple to use)
  2. ThreadPoolExecutor parameters: corePoolSize (number of core threads, by default the core threads are always alive in the thread pool, even if they are idle; unless the allowCoreThreadTimeOut property of ThreadPoolExecutor is set to true, the idle core threads will wait for new tasks to arrive at this time. There is a timeout strategy, once the timeout period set by keepAliveTime is exceeded, the idle core thread will be terminated), maximumPoolSize (the maximum number of threads, including the number of core threads + the number of non-core threads, after the number of active threads reaches this number, subsequent new tasks will be blocked), keepAliveTime (the timeout period when non-core threads are idle, for non-core threads, if the idle time exceeds this time, non-core threads will be recycled; when the allowCoreThreadTimeOut attribute is set to true, this timeout time will be for core threads effect), unit (used to specify the time unit of the keepAliveTime parameter), workQueue (saves the blocking queue waiting to execute tasks, and the Runable objects submitted through the execute method of the thread pool will be stored in the queue), threadFactory (thread factory, for threads The pool provides the creation of new threads), handler (rejectedExecutionHandler object, when the task queue is full, and the active thread in the thread pool has reached the maximum limit or cannot successfully execute the task, then ThreadPoolExecutor will call the rejectedExecution method of RejectedExecutionHandler)
  3. Thread pool execution process: Submit tasks—whether the number of core threads is full (create core threads to execute tasks if they are not full)—whether the task queue is full (join the queue if it is not full)—whether the thread pool is full (if it is not full, Create a non-core thread to execute the task) - refuse to execute (call handler.rejectedExecution to notify the caller)
  4. newFixedThreadPool(): Internal ThreadPoolExecutor implementation, new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()) - only core threads, and these threads will not be recycled, there is no timeout mechanism, the use of LinkedBlockingQueue lies in its Unbounded (no limit on task queue size)
  5. newCachedThreadPool(): (0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS, new SynchronousQueue()) —— There is no core thread, the maximum number of threads is an integer maximum, idle threads for 60s will be recycled, using SynchronousQueue (internal is an empty collection, the size of the task queue is 0, if the existing thread cannot receive the task, a new thread will be created to execute the task)
  6. newScheduledThreadPool(): (corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedWorkQueue())——The number of core threads is fixed, and the maximum number of threads is an integer maximum. When non-core threads are in the restricted state, they will be recycled immediately, creating a A thread pool that executes tasks regularly or periodically, and the return value is ScheduledExecutorService
  7. ScheduledExecutorService: schedule method (execute the task after a certain time delay), scheduleAtFixedRate (after a certain time delay, execute the task periodically at a certain interval, the time interval is the interval from the execution of the previous task to the start of the next task, this series of tasks The trigger time is predictable), scheduleWithFixedDelay (the time interval is the interval from the end of the execution of the previous task to the start of the next task, the trigger time of this series of tasks is unpredictable)
  8. newSingleThreadExecutor():new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue())
  9. Thread pool usage: CPU-intensive tasks (the number of threads in the thread pool should be as small as possible, such as configuring a thread pool with N+1 threads), IO-intensive tasks (IO operation speed is much lower than CPU speed, and most of the CPU time In the idle state, the thread pool can be configured with as many threads as possible to improve CPU utilization, such as 2*N), mixed tasks (split into CPU-intensive and IO-intensive, when the execution time of these two types of tasks is almost the same, through The throughput of splitting and re-execution is higher than the throughput of serial execution, but if there is a data-level gap in the execution time of these two types of tasks, then there is no meaning of splitting)

Lock

  1. Deadlock generation conditions: Mutual exclusion conditions (a resource can only be used by one thread at a time), request and hold conditions (when a thread is blocked by requesting resources, keep the obtained resources), non-deprivation conditions (threads The resources that have been obtained cannot be forcibly deprived before they are used up), circular waiting conditions (a head-to-tail circular waiting resource relationship is formed between several threads)
  2. Deadlock classification and solutions: static lock order deadlock (all threads that need multiple locks must acquire locks in the same order), dynamic lock order deadlock (use System.identifyHashCode to define the order of locks, ensure All threads acquire locks in the same order), deadlocks between collaborating objects (need to use open calls (an open call is to call an external method without holding a lock), avoid calling an external method while holding a lock method)
  3. Reentrant lock: When a thread obtains an object, it can obtain the object lock again when it requests the object lock again, that is to say, it can acquire its own internal lock again, Java built-in lock (synchronized) and Lock (ReentrantLock) reentrant
  4. Fair lock: Threads with low priority may not be able to obtain CPU execution rights all the time. Fair locks can ensure that threads are executed in chronological order to avoid starvation, but fair locks are relatively inefficient because an ordered queue needs to be maintained to achieve Sequential execution, ReentrantLock is a kind of fair lock. Passing true in the construction method is a fair lock, and passing false is an unfair lock. The default is false
  5. The difference between synchronized and Lock: a. Lock is an interface, while synchronized is a keyword in Java, and synchronized is a built-in language implementation; b. When an exception occurs, synchronized will automatically release the lock held by the thread, so it will not cause death. The lock phenomenon occurs, and when an exception occurs in the Lock, if the lock is not actively released through unLock(), it is likely to cause a deadlock phenomenon, so when using the Lock, the lock needs to be released in the finally block; c, Lock can let those waiting for the lock Threads respond to interrupts, but synchronized does not. When using synchronized, the waiting thread will wait forever and cannot respond to interrupts; d. Through Lock, you can know whether the lock has been successfully acquired, but synchronized cannot do it; e. Lock can improve Efficiency of read operations by multiple threads

volatile

  1. Atomicity: One or more operations, either all of them will be executed without interruption by any factors, or none of them will be executed
  2. Visibility: When multiple threads access the same variable, one thread modifies the value of this variable, other threads can immediately see the modified value
  3. Orderliness: The order in which the program is executed is executed in the order in which the code is executed
  4. Instruction reordering: In order to improve the efficiency of program operation, the processor may optimize the input code. It does not guarantee that the order of execution of each statement in the program is consistent with the order in the code, but it will ensure that the final execution result of the program and the order of code execution are Consistent; instruction reordering will not affect the execution of a single thread, but will affect the correctness of concurrent execution of threads
  5. Locks and atomicity, visible rows, and orderliness: a. The Java memory model only guarantees that basic reading and assignment are atomic operations. If you want to achieve atomicity in a wider range of operations, you can use synchronized and Lock to achieve it; b. Visibility can also be guaranteed through synchronized and Lock. Only one thread acquires the lock at the same time and then executes the synchronization code, and the modification of the variable will be refreshed to the main memory before the lock is released; c, synchronized and Lock can also guarantee the order
  6. Volatile and atomicity, visibility, and orderliness: a. Volatile cannot ensure that any operation on variables is atomic, and self-increment operations are not atomic operations. The atomic series brought by Java5, such as AtomicInteger, use CAS (Compare And Swap ) can guarantee the atomicity of the operation; b. volatile guarantees visibility. When a shared variable is modified by volatile, it will ensure that the modified value will be updated to the main memory immediately. When other threads need to read, its cache will be invalid, it will go to the memory to read the new value; c, volatile can guarantee the order, prohibit the reordering of instructions, the execution order of the previous/following statement of the statement where the volatile variable is located in a method body will not change, but the former/ The execution order of the internal multiple statements in the following statement is not guaranteed
  7. volatile application scenario: based on multi-threading, a. as a state switch; b. double check in singleton mode (the first empty check is for efficiency to avoid locking, the second empty check is for concurrency safety, volatile avoids the new statement instruction reordering operation)

JVM

memory area

  1. Method area (public): store data such as class information loaded by the virtual machine, constants, static constants, code compiled by the just-in-time compiler, including constant pools (users store various literals and symbol references generated by the compiler), exceptions Status OutOfMemoryError
  2. Heap (public): It is the largest piece of memory managed by the JVM. Its sole purpose is to store instance objects. Almost all object instances are allocated here; the Java heap is the main area managed by the garbage collector, and is often called " GC heap", exception status OutOfMemoryError
  3. Virtual machine stack (private thread): describes the memory model of Java method execution; each method will create a stack frame when it is executed, and the user stores local variable table, operand stack, dynamic connection, method exit and other information; each The process from the call to the completion of the method corresponds to the process of a stack frame being pushed into the stack and popped out of the stack in the virtual machine stack; two exception states OutOfMemoryError and StackOverflowError are defined for this area
  4. Native method stack (thread private): similar to the virtual machine stack, the difference is that the virtual machine stack executes Java methods for the virtual machine, while the local method stack serves the Native method used by the virtual machine
  5. Program counter (thread-private): a small piece of memory, the line number indicator of the bytecode executed by the current thread; when the bytecode interpreter works, it selects the next byte to be executed by changing the value of this counter code instruction

memory model

  1. The purpose of the Java memory model: to shield the memory access differences of various hardware and operating systems, so that Java programs can achieve consistent memory access effects on various platforms
  2. The main goal: to define the access rules of each variable in the program, that is, the underlying details of storing variables in the memory and taking them out of the memory in the virtual machine (the variables here are different from the variables mentioned in Java. It is Includes instance fields, static fields, and elements that make up an array object, but excludes local variables and method parameters)
  3. Variables of main memory and thread working memory: The Java memory model stipulates that all variables are stored in the main memory, and each thread saves the variables used by the thread in its own working memory (these variables are copied from the main memory and saved All operations (reading and assignment) on variables by threads must be performed in the working memory, and different threads cannot directly access the variables in the working memory of each other, and the transfer of variable values ​​​​between threads needs to be completed through the main memory

class loading mechanism

  1. Definition: Load the class file into the memory, verify, prepare, parse and initialize it, and finally form a Java type that can be directly used by the virtual machine
  2. The life cycle of a class: load, connect (validate, prepare, resolve), initialize, use and unload
  3. Trigger class loading timing: new, static field, static method, reflection, initialize the parent class first when initializing the class
  4. The specific process of class loading: loading (a, through the fully qualified class name, the class loader obtains the binary byte stream of the class; b, converts the static storage structure represented by this byte stream into a runtime data structure in the method area ; c. Generate a Class object representing this class in memory, as various data access entries for this class in the method area), verification (Class file format, metadata verification, bytecode verification, symbol reference verification), preparation (in The method area allocates memory for class variables and sets initial values), resolution (the virtual machine replaces symbol references in the constant pool with direct references, dynamic and static resolution), initialization (executes class constructors (different from class constructors, There is no need to explicitly call the parent class constructor, the virtual machine guarantees that the parent class constructor has been executed before the subclass method is executed), static code blocks, and assigning values ​​​​to class variables)
  5. Class loader classification: mainly divided into two categories, bootstrap class loader (Bootstrap ClassLoader, C++ language implementation (for HotSpot), responsible for loading Java core classes, loading class libraries stored in the \lib directory or in the path specified by the -Xbootclasspath parameter into memory), other class loaders (implemented by the Java language, inherited from the abstract class ClassLoader. The extension class loader——Extension ClassLoader, implemented by the Java language, is responsible for loading classes other than the Java extension core class, loading \lib\ext Directory or all class libraries in the path specified by the java.ext.dirs system variable; application class loader——Application ClassLoader, implemented in Java language, the default loader, responsible for loading the specified class library on the user class path classpath, through ClassLoader.getSystemClassLoader () method to get directly
  6. Android class loader: The most important class loaders in Android are the following 4, BootClassLoader (loads the class bytecode file in the Android Framework layer, similar to Java's Bootstrap ClassLoader but implemented in Java, the code is inside the ClassLoader file), PathClassLoader ( Load the class bytecode file of the Apk that has been installed in the system (similar to App ClassLoader in Java), DexClassLoader (load the class bytecode file in the specified directory (similar to Custom ClassLoader in Java)), BaseDexClassLoader (the parent of PathClassLoader and DexClassLoader kind)
  7. Parental Delegation Model: Custom Class Loader——Application ClassLoader——Extension ClassLoader——Bootstrap ClassLoader
  8. Parental delegation model code implementation: the loadClass method in ClassLoader implements the parental delegation model, and the custom class loader mainly rewrites the findClass method

garbage collection mechanism

  1. Garbage collection algorithm: mark-clear algorithm (mark and clear are not efficient, resulting in a large number of memory fragments), copy algorithm (in order to solve the efficiency problem, the memory is divided into two pieces of equal size, the allocation efficiency is high but the memory is reduced by half), mark- Finishing algorithm (when the object survival rate is high, the efficiency of the copy algorithm becomes low, and the marking process is still the same as the "mark-clear" algorithm, but the next step is not to clean up the recyclable objects directly, but to move all surviving objects to one end, and then Directly clean up the memory beyond the boundary), generational collection algorithm (the new generation uses the copy algorithm, and the old generation uses mark clearing or mark finishing to reclaim Java heap memory)
  2. Age in the JVM: Cenozoic (1 Eden area for newly created objects and 2 Survivor areas (From Survivor area and To Survivor area) for surviving objects, the default memory division ratio is 8:1, "Eden" survives during Minor GC The object is copied to "To", and the object whose age has not reached the threshold in the "From" area is copied to the "To" area, and then "From" and "To" will exchange roles to ensure that the Survivor area named To is empty), the old Age (objects whose age reaches the threshold in the "From" area will be moved to the old age; after the "To" area is filled, all objects will be moved to the old age)
  3. Minor GC and Full/Major GC: Minor GC (occurs in the new generation of garbage collection, very frequent Major), Full/Major GC (occurs in the old age, Major GC is usually accompanied by at least one Minor GC, and the speed of Major GC more than 10 times slower than Minor GC)
  4. Space allocation guarantee: Before Minor GC occurs, the virtual machine first checks the maximum available contiguous space in the old generation, whether it is larger than the total space of all objects in the new generation, if it is larger, it can ensure that Minor GC is safe, if it is smaller, it is possible to perform Full GC

How to tell if an object is dead

  1. Reference counting method: Add a reference counter to the object. When there is one more reference, the counter will be incremented by 1. When the reference becomes invalid, the counter will be decremented by 1. The counter is 0 to indicate that the object is no longer used. JVM does not use this method because it is difficult to solve the problem between objects. The problem of mutual circular references
  2. Reachability analysis algorithm: GC Roots objects (Java stack objects, Native stack objects, static objects in the method area and final objects), algorithm description (using a series of GC Roots objects as the starting point, starting from these nodes to search downwards, walking The passed path is called a reference chain. When there is no reference chain connecting an object to GC Roots (that is, the object is unreachable from GC Roots), it proves that the object is unavailable, and they will be judged as recyclable objects ), two marking processes for declaring the death of the object (the object is not connected to GC Roots, it will be marked for the first time and screened once (whether it is necessary to execute the finalize method for this object), if the object is re-referenced in finalie() If any object on the chain establishes an association, it will be removed from the "to be recycled" collection at the second mark, but if no association is established, it will be recycled)
  3. Whether the object survives is related to references: 4 major references, strong references (OOM will not recycle objects), soft references (recycling when memory is insufficient (before OOM), such as: image cache), weak references (recycling at the next GC, to prevent memory leak), phantom reference (may be recycled at any time, the only purpose of setting a phantom reference for an object is to get a system notification when the object is reclaimed by GC)


Java

gather

collection overview

HashMap

ConcurrentHashMap

generic

reflection

annotation

I流

Exception, shallow copy and new features of Java8

java exception

deep copy

Java8 new features

concurrency

thread

Thread Pool

Lock

volatile

JVM

memory area

memory model

class loading mechanism

garbage collection mechanism

How to tell if an object is dead


Android development interview series articles:


Guess you like

Origin blog.csdn.net/Agg_bin/article/details/129408320