Niuke.com Java Wrong Question Summary (1)

table of Contents

One, java concurrency

Second, the length of string and array

Three, Java variable naming

Four, CMS garbage collection

Five, singleton design pattern

Six, the difference between Hashtable and HashMap


 

One, java concurrency

Analysis:

  • A. CopyOnWriteArrayList is suitable for concurrent scenarios where write less and read more
    • Read operations are not locked, read and write are mutually exclusive, and write and write are mutually exclusive; suitable for scenarios with more reads and less writes
    • Reference URL: "CopyOnWriteArrayList and ReentrantReadWriteLock" https://blog.csdn.net/lovesman/article/details/107190307
  • B. ReadWriteLock is a read-write lock. It requires mutual exclusion between writing and writing, mutual exclusion between reading and writing, and concurrent execution between reading and reading . Can improve efficiency when reading more and writing less
  • C. ConcurrentHashMap is a synchronous HashMap, read operation is not locked, write operation is locked
  • D. Volatile only guarantees the visibility of multi-threaded operations, and does not guarantee atomicity. The self-increment operation is not an atomic operation (including reading variables, variable +1, and writing to memory), and there may be security issues during execution.
    • concept
      • Volatile is a type modifier. The role of volatile is to be used as an instruction keyword to ensure that this instruction will not be omitted due to compiler optimization
    • characteristic
      • This guarantees the visibility when different threads operate on this variable, that is, if one thread modifies the value of a variable, the new value is immediately visible to other threads. (Achieve visibility)
      • Reordering of instructions is prohibited. (Achieving orderliness)
      • Volatile can only guarantee the atomicity of a single read/write. i++ This operation cannot guarantee atomicity. Regarding volatile atomicity, it can be understood that a single read/write of a volatile variable is regarded as using the same lock to synchronize these single read/write operations.
    • Reference URL: "The volatile keyword, do you really understand it?" Https://zhuanlan.zhihu.com/p/138819184 , "Talking about the failure of volatile in the case of i++" https://blog.csdn.net/liuzhixiong_521/article/details/85246543

 

 

Second, the length of string and array

Analysis:

  1. String obtains the length using the length() method, and for the array type, we directly use the attribute length to obtain the length, so we should use the length to obtain the length of the String[] array type;
  2. In summary, because the original string does not contain a separator, it is directly returned to the original string, and only an empty string array is split, so the result is 1. (Note that although the original string is empty and the string array is empty, this empty string will also be counted as an element)

 

Three, Java variable naming

Analysis:

Java identifiers consist of numbers, letters and underscores (_), dollar signs ($) or yuan signs (¥).

In Java, it is case-sensitive, and it is also required that the first digit cannot be a number, and it can be an underscore . Most importantly, Java keywords cannot be used as Java identifiers.

 

Four, CMS garbage collection

Analysis:

The full name of CMS is  Concurrent Mark Sweep . It is a concurrent garbage collector that uses a mark-sweep algorithm to obtain the shortest recovery pause time at the expense of throughput. For applications that require server response speed, this The garbage collector is very suitable.

The basic algorithm of CMS is: mark-clear. Its process can be divided into the following 6 steps:

  • STW initial mark
    • At this stage, the virtual machine needs to stop the task being executed, the official name is STW (Stop The Word). This process starts from the "root object" of the garbage collection, and only scans the objects that can be directly associated with the "root object" and marks them. So although this process suspended the entire JVM, it was quickly completed .
  • Concurrent marking
    • This stage follows the initial marking stage, and continues to trace the marking downwards on the basis of the initial marking. In the concurrent marking phase, the application thread and the concurrent marking thread execute concurrently, so the user will not feel a pause .
  • Concurrent precleaning
    • The concurrent pre-cleanup phase is still concurrent. At this stage, the virtual machine searches for objects that have entered the old generation during the concurrent marking phase (some objects may be promoted from the young generation to the old generation, or some objects may be allocated to the old generation). By rescanning, the work of "re-marking" in the next stage is reduced, because the next stage will Stop The World.
  • STW remark
    • At this stage, the virtual machine is suspended, and the collector thread scans the remaining objects in the CMS heap. Scanning starts from the "root object" and goes down, and handles the object association.
  • Concurrent sweeping
    • To clean up garbage objects, the collector thread and the application thread execute concurrently at this stage .
  • Concurrent reset
    • At this stage, reset the data structure of the CMS collector and wait for the next garbage collection.

 

Five, singleton design pattern

Analysis:

  • Singleton design pattern definition
    • Ensure that there is only one instance of a class and provide a global access point for that instance.
    • The advantage of this is that for some instances, only one global is needed. Using the singleton mode can avoid a globally used class, which is frequently created and destroyed, which consumes system resources.
  • Design elements of the singleton pattern
    • Create a private constructor (ensure that only the singleton class can create an instance by itself)
    • Create a private static variable (make sure there is only one instance)
    • Create a public static function (provide the user with a calling method)

The realization of the singleton design pattern and their respective advantages and disadvantages:

1. Lazy (unsafe thread)

public class Singleton { 
    private static Singleton uniqueInstance;
    private Singleton() {}
    public static Singleton getUniqueInstance() { 
        if (uniqueInstance == null) {
            uniqueInstance = new Singleton();
        } return uniqueInstance;
    }
}
  • Note: The instance is not created first, and the instance is created when it is called for the first time, so it is called the lazy man.
  • Advantages: The instantiation is delayed. If you do not need to use this class, it will not be instantiated, saving system resources.
  • Disadvantages: thread is not safe, in a multi-threaded environment, if multiple threads enter if (uniqueInstance == null) at the same time, if it has not been instantiated at this time, that is, uniqueInstance == null, then there will be multiple threads executing uniqueInstance = new Singleton();, multiple instances will be instantiated;
  • Solution: Add a lock on the getUniqueInstance() method: private static synchronized Singleton getUinqueInstance() to avoid multiple threads from acquiring instances at the same time

 

2. Hungry Chinese style (thread safety)

public class Singleton {
    private static Singleton uniqueInstance = new Singleton();
    private Singleton() {}
    public static Singleton getUniqueInstance() {
        return uniqueInstance;
    }
}
  • Note: Regardless of whether you need to use this instance, instantiate the instance directly (same as a starving ghost), and then when you need to use it, you can directly adjust the method to use it.
  • Advantages: an instance is instantiated in advance to avoid thread insecurity problems.
  • Disadvantages: The instance is instantiated directly, and the instantiation is no longer delayed; if the system does not use this instance, or the system runs for a long time before needing to use this instance, it will waste the resources of the operating system

 

3. Implementation of double check lock (thread safety)

public class Singleton {
    private volatile static Singleton uniqueInstance; 
    private Singleton() {}
    public static Singleton getUniqueInstance() {
        if (uniqueInstance == null) {
            synchronized (Singleton.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new Singleton();
                }
            }
        }
        return uniqueInstance;
    }
}
  • Description: Double check lock is equivalent to a lazy man with improved thread safety.
    • The disadvantage of thread-safe lazy style is performance degradation. The reason is that even though the instance has been instantiated, there will still be a lock every time. And now, we changed the position of the lock and added one more check. That is, first determine whether the instance already exists, if it already exists, the locked method in the judgment method will not be executed. And if, before instantiation, multiple threads go in, it's okay, because the method inside has a lock, only one thread will enter the innermost method and instantiate the instance. In this way, at most the most, that is, at the first instantiation, there will be thread blocking, and there will be no more thread blocking problems in the subsequent.
    • Why use the volatile keyword to modify the uniqueInstance instance variable?
    • uniqueInstance = new Singleton(); This code is executed in three steps:
      • 1. Allocate memory space for uniqueInstance
      • 2. Initialize uniqueInstance
      • 3. Point uniqueInstance to the allocated memory address
    • The normal execution order is of course 1>2>3, but due to the nature of instruction rearrangement of the JVM, the execution order may become 1>3>2.
    • In a single-threaded environment, there is no problem with reordering instructions; in a multi-threaded environment, some threads may get uninitialized instances.
    • For example: Thread A only executes 1 and 3, at this time thread B calls getUniqueInstance() and finds that the uniqueInstance is not empty, and then obtains the uniqueInstance instance, but in fact, the uniqueInstance has not been initialized yet.
    • The solution is to add a volatile keyword to modify uniqueInstance. Volatile will prohibit the rearrangement of JVM instructions, which can ensure safe operation in a multi-threaded environment.
  • Advantages: delayed instantiation, saving resources; thread-safe; and compared to thread-safe lazy style, performance is improved.
  • Disadvantages: The volatile keyword also has some impact on performance.

 

4. Static internal class implementation (thread safety)

public class Singleton { 
    private Singleton() {} 
    private static class SingletonHolder { 
        private static final Singleton INSTANCE = new Singleton();
    } 
    public static Singleton getUniqueInstance() {
        return SingletonHolder.INSTANCE; 
    }
}
  • Description:
    • First, when the outer class Singleton is loaded, the static inner class SingletonHolder is not loaded into memory.
    • When the getUniqueInstance() method is called, return SingletonHolder.INSTANCE;  
    • When SingletonHolder.INSTANCE is triggered, the static internal class SingletonHolder will be loaded into memory and the INSTANCE instance will be initialized, and the JVM will ensure that INSTANCE is instantiated only once.
  • Advantages: delay instantiation, saving resources; and thread safety; performance is also improved.

 

5. Enumeration class implementation (thread safety)

public enum Singleton {
    INSTANCE; //添加自己需要的操作 public void doSomeThing() {}
}
  • Note: The creation of the default enumeration instance is thread-safe, and is a singleton in any case.
  • Advantages: simple writing, thread safety, natural prevention of reflection and deserialization calls.

 

Prevent deserialization

Serialization : the process of converting java objects into byte sequences;

Deserialization : the process of creating a new java object in memory through these byte sequences;

In other words, deserialization writes a singleton instance object to disk and then reads it back, thereby obtaining a new instance.

We want to prevent deserialization and avoid getting multiple instances.

The enumeration class naturally prevents deserialization.

Other singleton modes can override the readResolve() method to prevent deserialization, make the instance unique , and override readResolve():

private Object readResolve() throws ObjectStreamException{ 
    return singleton;
}

 

Six, the difference between Hashtable and HashMap

Analysis:

  • A, ×, Hashtable is a hash table, this class inherits from the Dictionary class and implements the Map interface
  • B, √, HashMap is implemented based on a hash table. Each element is a key-value pair. The conflict problem is resolved through a singly linked list. When the capacity is insufficient (exceeding the threshold), it will also automatically grow. This class inherits AbstractMap and implements the Map interface
  • C, √, Hashtable is thread-safe, while HashMap is thread-unsafe. The method in Hashtable is Synchronize, and the method in HashMap is non-Synchronize by default.
  • D, √, what is said is correct, but it does not meet the meaning of the question
  • E, √, the sentence cannot be faulted.

 

The difference between Hashtable and HashMap:

  • 1. The inherited parent class is different
    • Hashtable inherits from Dictionary class
    • HashMap inherits from AbstractMap class
    • But both implement the Map interface
  • 2. Thread safety
    • Hashtable is synchronized (Synchronize is used in the method) and is thread-safe
    • HashMap is unsynchronized (Synchronize by default in the method), which is thread-unsafe
  • 3. Is there a contains method
    • Hashtable has a contains(Object value) method, which has the same function as containsValue(Object value)
    • HashMap removed the contains method of Hashtable and changed it to containsValue(Object value) and containsKey(Object key)
  • 4. Whether to allow null values
    • In Hashtable, neither key nor value are allowed to appear null values
    • HashMap allows null values ​​(both key and value are acceptable), because null can be used as a key in HashMap, and its corresponding value can have multiple nulls
  • 5. Traverse method
    • HashTable使用Enumeration
    • HashMap uses Iterator
  • 6. Hash value
    • Hashtable directly uses the hashCode of the object

      //hashCode is a value of int type calculated by jdk according to the address or string or number of the object
      int hash = key.hashCode();
      int index = (hash & 0x7FFFFFFF)% tab.length;

    • HashMap needs to recalculate the key value and hash value

      int hash = hash(k);
      int i = indexFor(hash, table.length);

      static int hash(Object x) {
        int h = x.hashCode();

        h += ~(h << 9);
        h ^= (h >>> 14);
        h += (h << 4);
        h ^= (h >>> 10);
        return h;
      }
      static int indexFor(int h, int length) {
        return h & (length-1);
      }

  • 7. Array initialization and expansion
    • The default size of the hash array in Hashtable is 11, and the increase method is 2*n+1 (n is the size of the current array)
    • The default size of the hash array in HashMap is 16, and the increase method is 2*n (n is the size of the current array)

 

 

 

 

Guess you like

Origin blog.csdn.net/weixin_39478524/article/details/114942159