2020 interview how manufacturers? Ali architect conscience to share the US group, drops Java Gang interview Zhenti

This article reprinted from: 2020 interview how manufacturers? Ali architect conscience to share the US group, drops Java Gang interview Zhenti


Inscription : This article will try to simulate live interview dialogue scene with spoken rather than written language, the use of question and answer format to show. Additionally, each accompanied by a problem are "stretched", this part is to help small partners a deeper understanding of some additional low-level details, may rarely directly involved in the interview, when is the right level of knowledge to improve their own reserve it.

A, Java foundation

1. Q: List and Set what's the difference?

Analysis : This problem usually want to examine are the interviewer that you understand these two data structures have been used to select based on time, so you can start from the data structures and some of the use cases are to be introduced

A: List, a list of the elements can be repeated. When the LinkedList ArrayList and common implementation, the former is the way to achieve an array, which is accomplished by a linked list, using a choice, it is generally considered the characteristics of the basic data structures, such as high efficiency of reading an array, a linked list insert high efficiency.

Set, collection, characterized by memory elements can not be repeated. Is commonly realized is HashSet and TreeSet, separate talk:

HashSet, the underlying implementation a HashMap, during storage, the presence of the key value, and the value stored in a unified object object. Duplication when it is judged by the first object hashcode, if not equal, a direct memory. If they are equal, and then the key will do equals judgment, if still equal, not stored, if not equal, then the deposit, we know, HashMap is an array + basic structure of the list, the same, in the HashSet, also by the same strategy , the list stored at the same location in the array.

TreeSet, when stored in a custom object, the object needs to implement the Comparable interface, rewrite collation. Usage scenarios generally need to ensure the orderly and uniqueness of the stored data. Underlying data structure is a self-balancing binary sort tree (red-black tree)

Extension :

  1. When it comes to HashMap, HashMap may lead directly to related topics, I find this question very much like to ask the interviewer, possibly because HashMap can talk more, can be well under test candidates on the underlying implementation details, the source read, inquisitive attitude.
  2. Involves a binary tree, the small end met once asked the red-black tree properties, as the preparation before too, with confidence and lovemaking session was about eleven to it, the result comes just a second characteristic, the interviewer asked : red-black tree is a balanced binary tree and ordinary What is the difference? Was forced to look ignorant like ... came back quickly make up the core of the difference is this: red-black tree is a binary search tree, binary tree need to spin, or in other ways (such as through a red-black tree can change color) to ensure the balance (otherwise it becomes a linked list structure, no time on the edge of the complex), red-black tree defined conditions relatively loose, that is in the process of balance, consumption is relatively small.
  3. Because HashSet disorder, in order to achieve an orderly purposes, do not want to use other data structures can be used LinkedHashSet. A brief description, like HashSet and HashMap relations, but also uses a LinkedHashMap, difference LinkedHashMap ordinary HashMap is that on top of the original data structure, in the form of a doubly linked list of all entry (note that is talked about in front of an array + each of the list elements in the list, do the connections) connected together, the insertion order is the order entry, you can guarantee the same iterative sequence and insertion sequence elements (ordering)

2. HashMap is thread-safe yet, why not thread safe?

Analysis : This question, since the interviewer asked, certainly some talk in this regard. This problem, in most cases, can be a clear and comprehensive description of the problem to the ins and outs, there is little the interviewer really take some source code to test. Of course, as a candidate, if we can understand very thorough, then the simple graph and writing and telling, as a supplement, or cameo.

A: ah, not thread safe. Mainly from two ways:

  • Inserting new data, the same result of the hash multithreading, the insertion position will be targeted to the same list at the same index in the array. Upon insertion, if the second thread is the first thread insertion moment is also inserted, may cause, the value of the front cover is inserted.
  • The second effect is not thread-safe at the time of expansion, expansion of all values ​​will re-hash, into the "array + list" structure after the new expansion in. May lead to cyclic linked list happens, so that when the next node reads the node, is never empty, that is when the famous CPU usage to 100% expansion situation.

Extension :

To do heart bottom, or need to know these know why the job so, the next source line and think about it, can we do chicken into chaos.

  1. Recommend a good look at the source code, source code is not the amount, the structure is relatively clear.
  2. For the case of cyclic linked list, I saw someone else to write the illustrated version of the article to find out, and put a link here, for reference: HashMap high concurrency issues

3. Q: What is the data structure that you use as an alternative to meet the requirements of thread-safe scene it?

Analysis : Here the general interviewer wants investigation is understanding ConcurrentHashMap, but there are also individual cases, involves HashTable, the small end it suffered losses in this area, obviously you can sum small knowledge with earlier, but because of inadequate preparation, and failed to complete answer.

A: In Java, provides the following data structure can solve thread safety issues:

  • HashTable, the principle is achieved through Synchronize synchronization lock to the read and write methods are locked manner. Although thread-safe, but inefficient, as long as there is to read and write, you can not do other operations.
  • SynchronizedMap (involving less, you can understand), conditional synchronization is provided a method of Collections class returns the multi-threaded version of the HashMap. Implementation is the basic method are added to the synchronization lock.
  • ConcurrentHashMap (highlight): According jdk versions, to realize there are differences.

java8 before, with segment (period map to achieve lock, 16 is a default period is the number of simultaneous support 16 can also be custom read unaffected), an array data structure (segment) + array (entry) + list for reading and writing little scenes. Atomic operations provided the putIfAbsent () (no add). segment inherited from ReentrantLock, as a lock.

java8, Node structure elements (implemented Entry Interface), a linked list data structure array +; Node be directly locked, smaller particle sizes. When the chain length is greater than 8, is converted into a red-black tree, of course, before the conversion, look at the length of the array, 64 is less than that achieved by the first expansion; Insert element, if this position is null, CAS insertion; if not is null, then inserted into a lock applied Synchronize list;

Extended :

  • We see that the default length of the array is 16, then the numbers have any meaning it? Have! Do arithmetic aging rate! The tricky part of the design. A time expansion is directly to the left bit operation, a shift, expansion is twice; Second modulo hash time, 32-bit hash value, right 28, left upper four bits, and then to this length- 1 is 15 (1111) bitwise aND operation, so that the data is evenly distributed.
  • ConcurrentHashMap get size in time is how to calculate it?

1.7size (), get the size of the segment, and then determines whether or not modified, if so, to re-acquire lock segment size, then put together all segment sizes;
implemented 1.8size () is used to do a volatile variable CAS modified, if high concurrency, but also the values stored to a volatile portion of the array. Have the values, the values of these two parts together. mappingcount () method and the size () method implementation as

  • hashmap can use null as a key and value, stored in the first node table array; hashtable does not allow key and value is null (this is in a small company down the interviewer asked, shame).
  • Understand some other data structures:
  • ConcurrentSkipListMap data orderly
  • ConcurrentSkipListSet can go heavy
  • hashset is hashmap implementation, internal memory is key, all the value is the same object

二、ThreadLocal

1. Q: Please talk about your understanding of the ThreadLocal.

Analysis : In a multithreaded environment, we often encounter this scenario: maintenance of a global variable. If you want to ensure (atomic or variable values modified) correctness of variable values, what means required to achieve it? Yes, to modify the code lock can be implemented to ensure that only one thread at a time to modify the variable value. Of course more than one way, and the same contract AtomicXXX can achieve this effect, principle, almost nothing more than to achieve concurrency through lock. So are there any other idea of it? There, ThreadLocal, realization of ideas can be described another way.

A: Each thread will have a Map (ThreadLocalMap), used to store objects to ThreadLocal we define as the key, the value of the name of our custom is of value pairs. And this Map, from us to write multithreaded programs inherit parent thread Thread. In this mechanism, to ensure isolation between multiple threads of the value of the variable.

Look at the source code, in order to get () method is the entry point:

public T get() {
	Thread t = Thread.currentThread();
	ThreadLocalMap map = getMap(t);
	if (map != null) {
		ThreadLocalMap.Entry e = map.getEntry(this);
		if (e != null) {
			@SuppressWarnings("unchecked")
			                  T result = (T)e.value;
			return result;
		}
	}
	return setInitialValue();
}

Focus is on the third line, the current thread as a parameter, we look at the getMap (t) did what?

ThreadLocalMap getMap(Thread t) {
	return t.threadLocals;
}

Yes, the object is to get the current threadLocals thread object, we can infer the return value of the method, the object is a ThreadLocalMap type. Then the object in which to define it? Continue to look at the source code:

public class Thread implements Runnable {
	......
	     ThreadLocal.ThreadLocalMap threadLocals = null;
	......
}

It is clear that is defined in the Thread class.

Extended : Memory leaks.

ThreadLocal objects are weak. In the GC, it will be directly recycled. In this case, Map of the key is null, value value still can not get timely release. The current strategy is when you call get, set, remove and other methods, will start to recover these values. But if it had not been invoked? Ah, it is easy to cause a memory leak. Of course, not because this is considered to be a weak reference memory leaks caused by, and should be, the design of the variable storage mechanism, leading to leakage. So when in use, should be promptly released (from the above description, you must have thought how reasonable release it?)

Three, Valotile

1. Q: You said at understanding Valotile, and usage scenarios.

Analysis : multi-threaded programming, the problem we have to solve concentrated in three areas:

  • Atomic: The simplest example is, i ++, in a multithreaded environment, the end result is uncertain, and why? ++ because such an operation, after being compiled to instruction, multiple instruction to complete. Then the situation is complicated by the encounter, it will lead to "cover" each other.
  • Visibility: popular explanation is that, in a variable A thread made changes in B thread, correctly read the results after modification. Study principle, is not directly cpu and memory, communication systems, but the variable is read into the cache inside the L1, L2 and the like, also called private data production stack. Modification is in an internal cache, but the timing is synchronized to the system memory can not be determined, with the time difference, when concurrent, it could lead to, read values, not current values.
  • Orderliness: here only said instruction reordering, the virtual machine after the code is compiled for the instruction execution, for the purposes of optimization, in ensuring the same result, you may adjust the order of execution of instructions.

A: valotile, can satisfy the visibility and order. But we can not guarantee atomicity.

  • Visibility is modified, the changes to the variable force is synchronized to the system memory. And other cpu read value their own internal cache and found that the value of valotile modified, will the internal cache, set to be invalid, then read from the system memory.
  • Orderliness, it is achieved through the memory barrier. A so-called memory barriers, to be understood that, in some instructions, the barrier instruction is inserted, to ensure, when the continue command behind the barrier, all preceding instructions have completed.

Extended : In writing singleton, we usually determined using double manner, the innermost layer:

instance = new Singleton()

In fact, this is also a potential problem: the phrase assignment, in fact, operates in three steps:

  • Allocate memory for the instance
  • Call the constructor to initialize variables Singleto
  • point on the object instance initialization step

In doing jvm instruction reordering optimized, the above steps b and c can not be guaranteed and may occur, c first execution, but did not initialize the object, this time other threads judgment and found non-null, but when in use, but no specific examples of the resulting error. So, we can use valotile to modify instance, to avoid the problem.

Fourth, multi-threaded --Synchronized

1. Q: You usually involves much more than multi-threaded programming? Talk about your understanding of the Synchronized lock

Analysis : more from the realization of the principle, to describe the working mechanism

A: In multi-threaded programming in order to achieve thread-safety purposes, we tend to be achieved by locking manner. It is java and Synchronized provided to one of our very important lock. It belongs to the locking jvm level, the underlying implementation is: during compilation, identified in the instruction to add some level achieved. Objects example, the synchronization block, the synchronization code will be added to the block sum of the monitorenter and monitorexit bytecode instructions, this instruction needs a reference to two types of parameters, to indicate locking and unlocking of the synchronization method is performed by the modifier plus acc_synchronized identifier is implemented. In the implementation of these instructions (identification), essentially the acquisition, possession, release the monitor lock object to implement mutual exclusion, that is, the same time, only one thread can successfully get to the lock object. We look for some added after the code is compiled byte code synchronized keyword. Compile ago:

public class test {
  public test() {
  }
  public static void main(String[] args) {
    synchronized(new Object()){
        int i = 0;
    }
  }
}

Compiled:

public class test extends java.lang.Object{
public test();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."":()V
   4:   nop
   5:   return

public static void main(java.lang.String[]);
  Code:
   0:   new     #2; //class Object
   3:   dup
   4:   invokespecial   #1; //Method java/lang/Object."":()V
   7:   dup
   8:   astore_1
   9:   monitorenter // Enter the monitor associated with object 
   10:  iconst_0
   11:  istore_2
   12:  nop
   13:  aload_1
   14:  monitorexit // Exit the monitor associated with object 
   15:  goto    23
   18:  astore_3
   19:  aload_1
   20:  monitorexit // Be sure to exit monitor... 
   21:  aload_3
   22:  athrow
   23:  nop
   24:  return
  Exception table:
   from   to  target type
   15    18   any
   21    18   any

}

Focus on the 14 lines and 20 lines.

When using Synchronized, the method used is to wait and notify (or notifyAll), their principle is, after calling the wait method, the thread so that the cpu resources, the lock is released into the waiting state into a queue waiting queue [first] . When there are other thread calls notify or notifyAll wakes up, will be waiting in the queue thread object, moved into a second blocking queue [queue], the state is blocked, waiting for the lock to be released (the timing of this release, determined by the virtual machine , not human intervention), began to compete lock.

Synchronized not interrupt blocking queue or queue of waiting threads.

Extended : Synchronized provides the following types of locks: biased lock, lock lightweight, heavyweight lock. In most cases, there is no multi-threading competition, but a common thread is repeatedly access the same lock. So a lot of consumption, in fact, is on the acquisition and release the lock. Synchronized has been optimized, it can be said Synchronized Although launched earlier, but efficiency is not worse than the subsequent launch of the Lock.

Biased locking : Introduced in jdk1.6, the purpose is to eliminate the synchronization primitives in the absence of competition (adult words are translated, even though the addition of synchronized keyword, but when there is no competition, no need to get done - hold - the release operation of the lock object to improve running performance). How to do it? When the lock object is first acquired thread A virtual opportunity to object header flag is set to 01, that is, on behalf of bias mode. A representative of the same time the thread ID, by way of CAS, to update the object lock MarkWord head. The next time the same thread lock application again, simply compare the thread ID can be. The above operation is successful, the success in reaching the synchronized block. If someone else is to compete the lock thread B, two cases processed differently:

  • If the thread A has been completed (and will not take the initiative to modify the lock state of the object) implementation will directly withdraw the lock status of the object is not locked, the flag is 00;
  • If thread A still holds the lock, the lock escalation as a lightweight lock.

Lightweight locks : JDK1.6 is introduced, lightweight, with respect to the use of mutex locks for the heavyweight. Competition occurs when a thread lock, not directly into the blocked state, but first try to do CAS modification operations into a spin, this procedure avoids the overhead of switching thread state, but to consume cpu resources. Detailed process is:

  1. Thread tries to enter the sync block, if the lock object is not locked, the thread corresponding to the current stack frame, the lock record to establish a space for storing copies of the lock object Mark Word.
  2. Then the JVM CAS MarkWord embodiment attempts to replace the contents of the lock object to point to the "record locking" pointer. If successful, the current thread holds the lock, locked in a lightweight state; if it fails, it will first check whether the current MarkWord point to "lock record" the current thread stack frame, if it is, it shows the current thread already has this lock, direct re-entry can be. Otherwise, it indicates that other thread holds the lock, then entered a spin (in fact, retry the CAS modify operations).
  3. When the lock is released, and the use of CAS in terms of MarkWord "locks on" the contents of the swap. If successful, the success of the release; if the incident, indicating that the current latched competition (modified by another thread in the MarkWord data), this time, the lock will be upgraded to heavyweight lock.

Heavyweight lock : that is the way we use the mutex lock to achieve when there is a multithreaded competition, as long as the lock did not get, will enter the blocked state, consumed mainly in the blocking - evoke - blocked - evoke the thread state switched on.

Three types of locks described above, it is responsible for managing the JVM to what type of lock, and lock upgrade (note, not downgraded) use.

Fifth, multi-threaded --Lock

1. Q: You usually involves much more than multi-threaded programming? Talk about your understanding of the Lock locks

Analysis : The best comparison in terms of the synchronized

answer:

In multi-threaded programming in order to achieve thread-safety purposes, we tend to be achieved by locking manner. Lock Lock is java code level to achieve, relative to synchronizedd in functionality, has been strengthened, mainly, fair locks, lock polling, time lock, interruptible lock, also adds multi-channel notification mechanism (Condition) , a lock can be used to manage a plurality of sync blocks. In addition, when used, must be manually release the lock.

Detailed analysis:

  • Lock achieve lock, mainly by means of a queue synchronizer (we often see AQS) to achieve. It comprises a variable to represent the state of int; a FIFO queue to store queued thread acquires resource.
  • When a thread application resources, is is to obtain current sync status, and be in line with expectations to determine whether, and if so, by CAS operation to modify the synchronization state of the variables identified Int. If not, the thread into the queue line (which is in the general case, when using tyrLock, is returned directly to obtain a lock failure).

Lock has an exclusive lock and a shared lock. Exclusive lock is at the same time, allowing only a single thread holds the lock; time to achieve shared lock and an exclusive lock is slightly different, not simply modify the synchronization status (such as 1 and 0), but get this value, when the value of It is greater than 0, i.e., successful identification acquire a shared lock (implicit meaning each thread to acquire the lock after successful, the value minus 1). Here attach an exclusive lock to realize source (source code fragment from the "art of java concurrent programming," and add their own comments):

public class Mutex implements Lock {  
  
    // 静态内部类,自定义同步器  
    private static class Sync extends AbstractQueuedSynchronizer{  
        // 该方法用于判断当前锁是否在独占模式下被占用状态  
        protected boolean isHeldExclusively(){  
            return getState() == 1;  
        }  
  
        // 获取锁!!! 
        public boolean tryAcquire(int acquires){ 
          //典型的CAS原子操作,如果初始状态为0,可以获得锁
            if (compareAndSetState(0, 1)){  
                setExclusiveOwnerThread(Thread.currentThread());  
                return true;  
            }  
            return false;  
        }  
  
        //释放锁,将当前状态设置为0  
        protected boolean tryRelease(int releases){  
            if (getState() == 0){  
                throw new IllegalMonitorStateException();  
            }  
            setExclusiveOwnerThread(null);  
            setState(0);  
            return true;  
        }  
  
        // 返回一个Condition,每个condition都包含了一个condition队列 ,这个后续再说 
        Condition newCondition(){  
            return new ConditionObject();  
        }  
    }
  • Lock lock, interruptible lock support, implementation principle is waiting in the queue thread, other threads can respond to interrupt signals initiated, InterruptdException throw an exception.
  • About synchronization queue, you need to know to get the synchronization state failed Thread, after being packaged as Node node, join the queue tail, this operation is a CAS operation to ensure thread safety, failure to infinite loop retry; and the head of the queue node, it is the current thread holding the lock. The node Once the lock is released, it will wake up the subsequent node.
  • Wake-up, like this, each blocking thread synchronization queue, are in a state spins, constantly trying to get a lock. Thus, when the first node releases the lock wake successor thread, thread to be awakened, also need to determine whether the former following the thread is the first thread is the acquisition synchronization status (lock) success.

Extended : Condition, multi-channel notification mechanism

  • In Synchronized lock, a wait, notify, notifyAll other methods to achieve the wait / notification mode. Then lock in the Condition fit, but also to achieve a similar pattern.
  • Its essence is achieved, a queue comprising a Condition, Condition defining a plurality, then there is a plurality of waiting queue, and the queue mentioned above in conjunction with synchronization. Synchronous queue - waiting queue model See

  • In the above model, call await method, corresponding to the (thread holds the lock) the first node of the synchronous queue, the queue waiting to move. Wake-up call to the signal method blocked thread, sucked correspond Condition wait queue head node (longest-waiting), moved into the synchronous queue.
  • Another point to add is that wake up the thread, call signal can wake up properly; after the termination of the thread in the other thread, the same will wake up, but wake up, just throw InterruptException exception.

This article reprinted from: 2020 interview how manufacturers? Ali architect conscience to share the US group, drops Java Gang interview Zhenti

Published 209 original articles · won praise 12 · views 10000 +

Guess you like

Origin blog.csdn.net/Java_supermanNO1/article/details/103895781