Java source code analysis and interview questions-queue interview questions in source code

This series of related blog, Mu class reference column Java source code and system manufacturers interviewer succinctly Zhenti
below this column is GitHub address:
Source resolved: https://github.com/luanqiu/java8
article Demo: HTTPS: // GitHub. com / luanqiu / java8_demo
classmates can look at it if necessary)

Java source code analysis and interview questions-queue interview questions in source code

Introductory phrase
queues face questions in terms of the source code, the general entrance from the interviewer will lock the thread pool, etc. As a matter of knowledge, slowly and asked to queue, because the lock, the thread pool we have not learned, so went straight to the theme of this chapter Let's start with the queue and see what interview questions are in the queue (there are many types of queues. In this article, when talking about the general characteristics of the queue, they are talking about the general characteristics of most of the queues. Instructions).

1 Interview questions

1.1 Talk about your understanding of queues, the difference between queues and collections.
Answer : Understanding of the queue:

  1. First of all, the queue itself is a container, and the bottom layer will also have different data structures. For example, LinkedBlockingQueue is a linked list structure at the bottom, so it can maintain the first-in first-out order. For example, the bottom layer of DelayQueue can be a queue or stack, so it can be guaranteed to be first-in, first-out, or The order of first-in, first-out, etc., the underlying data structure is different, which also causes different operation implementation;
  2. Some queues (such as LinkedBlockingQueue) provide a temporary storage function, we can put data into the queue, and we can also get data from the queue, both can be done at the same time;
  3. The queue decouples the party that produces data from the party that consumes data. The producer only controls production, and the consumer only consumes. There is no necessary connection between the two. The queue is like a data channel between the producer and the consumer, such as LinkedBlockingQueue ;
  4. The queue can also manage consumers and producers. For example, when the queue is full and some producers are still delivering data, the queue can block the producer and prevent it from being delivered. For example, when the queue is empty, there is consumption When the person comes to get the data, the queue can let the consumer hodler live, and when there is data, wake up the consumer and let the consumer return the data, such as ArrayBlockingQueue;
  5. The queue also provides a blocking function. For example, when we get data from the queue, but there is no data in the queue, the thread will block until the queue has data available to return.

The difference between queue and collection:

  1. Similar to collections, queues (some exceptions) and collections provide data storage functions. The underlying storage data structure is somewhat similar. For example, LinkedBlockingQueue and LinkedHashMap both use linked lists, and ArrayBlockingQueue and ArrayList use both. Is an array.
  2. The difference with the collection:
    • The underlying storage structure of some queues and some collections is very similar, but in order to accomplish different things, the APIs provided by the two and their underlying operations are different.

    • The queue provides a blocking function, which allows simple management of consumers and producers. When the queue is empty, it will block the consumer. After other threads perform the put operation, the blocked consumer will be awakened to allow the consumer to consume the data. , Also when the queue is full.

    • Decoupling the producer and the consumer, the queue is like a pipeline between the producer and the consumer. The producer only throws it in, and the consumer only consumes continuously. The two do not care about each other.

1.2 Which queues have the function of blocking and how are they blocked?
Answer : The queue mainly provides two blocking functions, as follows:

  1. LinkedBlockingQueue and ArrayBlockingQueue are two types of blocking queues. The capacity of the former is the maximum value of Integer, and the size of the latter array is fixed. Both blocking queues can specify the capacity. When the queue is full, if there is thread put data, the thread will Blocked, until other threads consume data, the blocked thread will wake up and continue to put. When the queue is empty, if there is a thread to take data, the thread will block until the queue is not empty and continue to take.
  2. SynchronousQueue Synchronous queue, when the thread is put, the corresponding thread must consume the data, the put thread can return, when the thread takes, the corresponding thread needs to put data, the take can return, otherwise the blocking, for example, thread A put data A1 to the queue. At this time, there is no consumer. Thread A cannot return and will block. Thread A cannot return until a thread consumes data A1.

1.3 How does the underlying layer block?
Answer : The queue itself does not implement the blocking function, but uses Condition's wait-and-wake mechanism. The underlying implementation of blocking is to change the state of the thread to sleep, as we will talk about in the lock section.

1.4 What is the difference between LinkedBlockingQueue and ArrayBlockingQueue?
Answer : The same point:
the blocking mechanism of the two is roughly the same. For example, when the queue is full and empty, the thread will block.

difference:

  1. The bottom layer of LinkedBlockingQueue is a linked list structure, and the capacity is the maximum value of Interge by default. The bottom layer of ArrayBlockingQueue is an array, and the capacity must be specified during initialization.
  2. The underlying structure of the two is different, so the underlying implementation of take, put, and remove is also different.

1.5 Is it safe to put data into the queue? why?
A : It is thread-safe. Before put, the queue will be automatically locked. After the put is completed, the lock will be automatically released, ensuring that only one thread can operate on the queue data at the same time. Take LinkedBlockingQueue as an example. When put, Add put lock, and only operate on the tail of the team. When take, it will add a take lock, and only operate on the head of the team. When remove, it will add both put and take locks, so various operations are thread-safe. , We can use it with confidence in our work.

1.6 Will it be locked when take? Since both put and take are locked, can only one of the methods be run at the same time.
Answer :

  1. Yes, it will also be locked when taking. For example, when LinkedBlockingQueue executes the take method, it will delete the current data while taking the data, which changes the data structure of the linked list, so it needs to be locked to ensure thread safety.
  2. This depends on the situation. For LinkedBlockingQueue, the put and take of the queue will be locked, but the locks of the two are different, so the two do not affect each other and can be performed at the same time. For ArrayBlockingQueue, put and take is the same lock, so only one method can run at a time.

1.7 What are the hazards of using the queue's put and take methods frequently in work and how to avoid them.
Answer : When the queue is full, using the put method will block until the queue is not full.
When the queue is empty, using the take method will block until the queue has data.

Both methods are infinite (forever, no timeout means) blocking method, it is easy to make all the threads blocked. When the flow is large, the machine has no threads available, so it is recommended to use the offer and poll methods when the flow is large Instead of the two, we only need to set the timeout blocking time. If the two methods do not get data outside the timeout time, they will return to the default value (LinkedBlockingQueue as an example), so that it will not cause heavy traffic, all Threads are blocked.

This is also one of the reasons why production accidents often occur. Trying to use the put and take methods can not be found in the usual self-test. Students who are not familiar with the source code will not realize that there will be problems. When online traffic comes in , It is likely to fail, so we usually need to be cautious when using queues in our work.

1.8 After putting data in the queue, is there a way to let the queue execute after a while?
Answer : Yes, DelayQueue provides this mechanism, which can be set to be executed after a certain period of time. The only disadvantage of this queue is that the data is stored in the memory. When restarting and power off, the data is easy to lose, so it is scheduled. We will not set the time for a long time, usually within a few seconds. If the scheduled time needs to be set for a long time, you can consider adopting 延迟队列中间件(this kind of middleware will persist the data, not afraid of power failure) to achieve.

1.9 Does DelayQueue have any requirements for elements? Can I put String in the queue?
Answer : DelayQueue requires that the elements must implement the Delayed interface, and the Delayed itself implements the Comparable interface. The role of the Delayed interface is to define how long it will time out and customize the timeout period for users. The Comparable interface is mainly used for the inter-element The sorting of the timeout time, the combination of the two, can make the elements that expire sooner in the front.

Therefore, it is not acceptable to put String in DelayQueue, and the compilation will not pass. When the DelayQueue class is defined, it is defined by a generic type. The generic type must be a subclass of the Delayed interface.

1.10 How does DelayQueue let elements that expire soon execute first?
Answer : The elements in DelayQueue both implement Delayed and Comparable interfaces, which will use the CompareTo method of Sortable to sort. We can use this function to implement the difference between the expiration time and the current time in the compareTo method, so the sooner the expired elements , The smaller the calculated difference, the earlier it will be executed.

1.11 How to check the size of SynchronousQueue?
Answer : This question is a trap. The question first sets the SynchronousQueue to check the size. In fact, SynchronousQueue itself has no capacity, so it cannot check the size of its capacity. Its internal size method is to return to death. 0.

1.12 There are several data structures at the bottom of SynchronousQueue, what is the difference between the two?
Answer : There are two types of data structures in the bottom layer, namely queue and stack.

The difference between the two: the
queue maintains the first-in first-out order, so the most advanced elements to be dequeued will be consumed first, which we call fair, and the stack is the first-in, first-out order, and the data that enters the stack first It may be consumed in the end, which we call unfair.
The data structure of the two is different, which leads to differences in the take and put methods. For details, see the "SynchronousQueue Source Code Analysis" chapter.

1.13 Assuming that the bottom of SynchronousQueue uses a stack, thread 1 is blocked by the take operation, and then thread 2 executes the put operation. How does thread 2 pass the put data to take at this time?
Answer : This is a good question, and it is also the core issue of understanding SynchronousQueue.

First, thread 1 is blocked. At this time, the stack head is thread 1. At this time, thread 2 performs a put operation, and the put data is assigned to the match attribute of the stack head, and thread 1 is woken up. After thread 1 is woken up, it gets With the match attribute in the stack header, you can get the put data.

Strictly speaking, it is not that the put operation directly transfers the data to the take, but the put operation changes the data of the stack header, so that the take can directly get the data from the stack header, and the stack header is the communication medium between the take and put operations .

1.14 If you want to use a fixed-size queue, there are several types of queues to choose from. What is the difference?
Answer : LinkedBlockingQueue and ArrayBlockingQueue can be used.

The former is a linked list, and the latter is an array. When the linked list is added, as long as the association between the new data and the tail data is established, the position of the index needs to be considered when the array is added (takeIndex and putIndex are recorded separately Take the index of the data and put the index of the data), if it increases to the last position of the array, it will start to be added again next time.

1.15 Can ArrayBlockingQueue be dynamically expanded? What to do when the last position of the array is used?
Answer : No, although the bottom layer of ArrayBlockingQueue is an array, it cannot be dynamically expanded.

Assuming that the put operation uses the last position of the array, the next put will need to restart from the position of array 0.

Assuming that the take operation uses the last position of the array, the next take will start from the position of array 0 again.

1.16 How do ArrayBlockingQueue take and put find the index position? Is it calculated using the hash algorithm?
Answer : ArrayBlockingQueue has two attributes, takeIndex and putIndex, which respectively identify the position of next take and put. Each time take and put are completed, they will be increased by one. Although the bottom layer is an array, it is different from HashMap and is not passed. Calculated by the hash algorithm.

2 Summary

Queues are the foundation of complex APIs such as locks and thread pools. Many interviewers will ask you the knowledge of queues when asking these APIs. If you do n’t answer well, the interviewer may think that you have only used locks and thread pools. However, the underlying principles and implementation are not fully understood, so the queue is still very important, but the source code of the queue is more complicated. It is recommended that you can try the debug method to understand the source code.

Published 40 original articles · won praise 1 · views 4982

Guess you like

Origin blog.csdn.net/aha_jasper/article/details/105525836