Análisis del código fuente de Java y preguntas de la entrevista: preguntas de la entrevista en cola en el código fuente

Esta serie de blog relacionado, Mu columna de referencia de clase Java de código fuente y del sistema fabricantes entrevistador sucinta Zhenti
por debajo de esta columna es la dirección de GitHub:
Fuente resolvió: https://github.com/luanqiu/java8
artículo Demostración: HTTPS: // GitHub. com / luanqiu / java8_demo los
compañeros de clase pueden verlo si es necesario)

Análisis del código fuente de Java y preguntas de la entrevista: preguntas de la entrevista en cola en el código fuente

frase introductoria
colas frente a las preguntas en términos del código fuente, la entrada general, por parte del entrevistador se bloqueará el grupo de subprocesos, etc. Como una cuestión de conocimiento, lentamente y se le preguntó a la cola, porque la cerradura, el grupo de subprocesos no hemos aprendido, por lo que fue directamente al tema de este capítulo Comencemos con la cola y veamos qué preguntas de la entrevista hay en la cola (hay muchos tipos de colas. En este artículo, cuando se habla de las características generales de la cola, se habla de las características generales de la mayoría de las colas. Instrucciones)

1 preguntas de la entrevista

1.1 Hable sobre su comprensión de las colas, la diferencia entre colas y colecciones.
Respuesta : Comprensión de la cola:

  1. En primer lugar, la cola en sí misma es un contenedor, y la capa inferior también tendrá diferentes estructuras de datos. Por ejemplo, LinkedBlockingQueue es una estructura de lista vinculada en la parte inferior, por lo que puede mantener el orden de primero en entrar, primero en salir. El orden de primero en entrar, primero en salir, etc., la estructura de datos subyacente es diferente, lo que también causa una implementación de operación diferente;
  2. Algunas colas (como LinkedBlockingQueue) proporcionan una función de almacenamiento temporal, podemos poner datos en la cola y también podemos obtener datos de la cola, ambos se pueden hacer al mismo tiempo;
  3. La cola desacopla a la parte que produce datos de la parte que consume datos. El productor solo controla la producción, y el consumidor solo consume. No hay conexión necesaria entre los dos. La cola es como un canal de datos entre el productor y el consumidor, como LinkedBlockingQueue ;
  4. La cola también puede administrar consumidores y productores. Por ejemplo, cuando la cola está llena y algunos productores todavía están entregando datos, la cola puede bloquear al productor y evitar que se entregue. Por ejemplo, cuando la cola está vacía, hay consumo Cuando la persona viene a obtener los datos, la cola puede dejar que el consumidor viva y, cuando haya datos, despertar al consumidor y dejar que el consumidor devuelva los datos, como ArrayBlockingQueue;
  5. La cola también proporciona una función de bloqueo. Por ejemplo, cuando obtenemos datos de la cola, pero no hay datos en la cola, el subproceso se bloqueará hasta que la cola tenga datos disponibles para devolver.

La diferencia entre cola y colección:

  1. Similar a las colecciones, las colas (algunas excepciones) y las colecciones proporcionan funciones de almacenamiento de datos. La estructura de datos de almacenamiento subyacente es algo similar. Por ejemplo, LinkedBlockingQueue y LinkedHashMap usan listas vinculadas, y ArrayBlockingQueue y ArrayList usan ambas. Es una matriz.
  2. La diferencia con la colección:
    • La estructura de almacenamiento subyacente de algunas colas y algunas colecciones es muy similar, pero para lograr cosas diferentes, las API proporcionadas por los dos y sus operaciones subyacentes son diferentes.

    • La cola proporciona una función de bloqueo que permite una gestión simple de los consumidores y productores. Cuando la cola está vacía, bloqueará al consumidor. Después de que otros subprocesos realicen la operación de colocación, el consumidor bloqueado se despertará para permitir que el consumidor consuma los datos. , También cuando la cola está llena.

    • Desacoplando al productor y al consumidor, la cola es como una tubería entre el productor y el consumidor. El productor solo lo tira y el consumidor solo consume continuamente. Los dos no se preocupan el uno por el otro.

1.2 ¿Qué colas tienen la función de bloqueo y cómo se bloquean?
Respuesta : La cola proporciona principalmente dos funciones de bloqueo, de la siguiente manera:

  1. LinkedBlockingQueue y ArrayBlockingQueue son dos tipos de colas de bloqueo. La capacidad de la primera es el valor máximo de Integer, y el tamaño de la última matriz es fijo. Ambas colas de bloqueo pueden especificar la capacidad. Cuando la cola está llena, si hay datos de subprocesos, el subproceso Bloqueado, hasta que otros subprocesos consuman datos, el subproceso bloqueado se activará y continuará colocando.Cuando la cola está vacía, si hay un subproceso para tomar datos, el subproceso se bloqueará hasta que la cola no esté vacía y continúe tomando.
  2. SynchronousQueue Cola sincrónica, cuando se coloca el subproceso, el subproceso correspondiente debe consumir los datos, el subproceso puesto puede regresar, cuando el subproceso toma, el subproceso correspondiente debe poner datos, la toma puede regresar, de lo contrario el bloqueo, por ejemplo, subproceso A coloca los datos A1 en la cola. En este momento, no hay consumidor. El subproceso A no puede regresar y se bloqueará. El subproceso A no puede regresar hasta que un subproceso consuma los datos A1.

1.3 ¿Cómo se bloquea la capa subyacente?
Respuesta : La cola en sí no implementa la función de bloqueo, sino que utiliza el mecanismo de espera y activación de la condición. La implementación subyacente del bloqueo es cambiar el estado del hilo a modo de suspensión, como veremos en la sección de bloqueo.

1.4 ¿Cuál es la diferencia entre LinkedBlockingQueue y ArrayBlockingQueue?
Respuesta : El mismo punto:
el mecanismo de bloqueo de los dos es más o menos el mismo. Por ejemplo, cuando la cola está llena y vacía, el hilo se bloqueará.

Diferencias:

  1. La capa inferior de LinkedBlockingQueue es una estructura de lista vinculada, y la capacidad es el valor máximo de Interge de forma predeterminada. La capa inferior de ArrayBlockingQueue es una matriz, y la capacidad debe especificarse durante la inicialización.
  2. La estructura subyacente de los dos es diferente, por lo que la implementación subyacente de take, put y remove también es diferente.

1.5 ¿Es seguro poner datos en la cola? Por qué
R : Es seguro para subprocesos. Antes de la colocación, la cola se bloqueará automáticamente. Una vez completada la colocación, el bloqueo se liberará automáticamente, asegurando que solo un subproceso pueda operar en los datos de la cola al mismo tiempo. Tome LinkedBlockingQueue como ejemplo. Cuando se pone, Agregue el bloqueo de colocación, y solo opere en la cola del equipo. Cuando tome, agregará un bloqueo de toma, y ​​solo operará en la cabeza del equipo. Cuando lo retire, agregará bloqueos de colocación y toma, por lo que varias operaciones son seguras para el hilo. Podemos usarlo con confianza en nuestro trabajo.

1.6 ¿Se bloqueará cuando se tome? Dado que tanto put como take están bloqueados, solo se puede ejecutar uno de los métodos al mismo tiempo.
Respuesta :

  1. Sí, también se bloqueará al tomar. Por ejemplo, cuando LinkedBlockingQueue ejecuta el método take, eliminará los datos actuales mientras toma los datos, lo que cambia la estructura de datos de la lista vinculada, por lo que debe bloquearse para garantizar la seguridad del subproceso.
  2. Esto depende de la situación. Para LinkedBlockingQueue, la colocación y la toma de la cola estarán bloqueadas, pero los bloqueos de los dos son diferentes, por lo que los dos no se afectan entre sí y se pueden realizar al mismo tiempo. Para ArrayBlockingQueue, poner y take es el mismo bloqueo, por lo que solo se puede ejecutar un método a la vez.

1.7 ¿Cuáles son los peligros de usar los métodos de poner y tomar de la cola con frecuencia en el trabajo y cómo evitarlos?
Respuesta : Cuando la cola está llena, el uso del método put se bloqueará hasta que la cola no esté llena.
Cuando la cola está vacía, el uso del método take se bloqueará hasta que la cola tenga datos.

Ambos métodos son un método de bloqueo infinito (siempre, sin tiempo de espera), es fácil bloquear todos los hilos. Cuando el flujo es grande, la máquina no tiene hilos disponibles, por lo que se recomienda utilizar los métodos de oferta y sondeo cuando el flujo es grande En lugar de los dos, solo necesitamos establecer el tiempo de bloqueo del tiempo de espera. Si los dos métodos no obtienen datos fuera del tiempo de espera, volverán al valor predeterminado (LinkedBlockingQueue como ejemplo), para que no cause tráfico pesado Los hilos están bloqueados.

Esta es también una de las razones por las que a menudo ocurren accidentes de producción. Intentar usar los métodos de poner y tomar no se puede encontrar en la autoevaluación habitual. Los estudiantes que no están familiarizados con el código fuente no se darán cuenta de que habrá problemas. Cuando entra el tráfico en línea Es probable que falle, por lo que generalmente debemos ser cautelosos al usar colas en nuestro trabajo.

1.8 Después de poner los datos en la cola, ¿hay alguna manera de permitir que la cola se ejecute después de un tiempo?
Respuesta : Sí, DelayQueue proporciona este mecanismo, que se puede configurar para que se ejecute después de un cierto período de tiempo. La única desventaja de esta cola es que los datos se almacenan en la memoria. Al reiniciar y apagar, los datos son fáciles de perder, por lo que se programa. No estableceremos el tiempo por un tiempo prolongado, por lo general en unos pocos segundos. Si el tiempo programado necesita establecerse durante un tiempo prolongado, puede considerar la adopción 延迟队列中间件(este tipo de middleware persistirá en los datos, sin temor a fallas en el suministro eléctrico).

1.9 ¿DelayQueue tiene algún requisito para los elementos? ¿Puedo poner String en la cola?
Respuesta : DelayQueue requiere que los elementos implementen la interfaz Retrasada, y el Retardado mismo implementa la interfaz Comparable. La función de la interfaz Retrasada es definir cuánto tiempo aguardará y personalizar el tiempo de espera para los usuarios. La interfaz Comparable se utiliza principalmente para el elemento intermedio La clasificación del tiempo de espera, la combinación de los dos, puede hacer que los elementos que caducan antes en el frente.

Por lo tanto, no es aceptable poner String en DelayQueue, y la compilación no pasará. Cuando se define la clase DelayQueue, se define por un tipo genérico. El tipo genérico debe ser una subclase de la interfaz Retrasada.

1.10 ¿Cómo DelayQueue permite que los elementos que caducan pronto se ejecuten primero?
Respuesta : Los elementos en DelayQueue implementan interfaces demoradas y comparables, que usarán el método CompareTo de Sortable para ordenar. Podemos usar esta función para implementar la diferencia entre el tiempo de vencimiento y el tiempo actual en el método compareTo, por lo que cuanto antes los elementos caducados Cuanto menor sea la diferencia calculada, antes se ejecutará.

1.11 ¿Cómo verificar el tamaño de SynchronousQueue?
Respuesta : Esta pregunta es una trampa. La pregunta primero establece el SynchronousQueue para verificar el tamaño. De hecho, SynchronousQueue en sí no tiene capacidad, por lo que no puede verificar el tamaño de su capacidad. Su método de tamaño interno es volver a la muerte. 0.

1.12 Hay varias estructuras de datos en la parte inferior de SynchronousQueue, ¿cuál es la diferencia entre los dos?
Respuesta : Hay dos tipos de estructuras de datos en la capa inferior, a saber, cola y pila.

La diferencia entre los dos: la
cola mantiene el orden de primero en entrar, primero en salir, por lo que los elementos más avanzados que se eliminarán se consumirán primero, lo que llamamos justo, y la pila es el orden de primero en entrar, primero en salir, y los datos que entran primero en la pila Puede ser consumido al final, lo que llamamos injusto.
La estructura de datos de los dos es diferente, lo que conduce a diferencias en los métodos take y put. Para más detalles, consulte el capítulo "Análisis del código fuente de SynchronousQueue".

1.13 Suponiendo que la parte inferior de SynchronousQueue usa una pila, el subproceso 1 es bloqueado por la operación take y luego el subproceso 2 ejecuta la operación put. ¿Cómo pasa el subproceso 2 los datos put para tomar en este momento?
Respuesta : Esta es una buena pregunta, y también es el tema central de entender SynchronousQueue.

Primero, se bloquea el subproceso 1. En este momento, el encabezado de la pila es el subproceso 1. En este momento, el subproceso 2 realiza una operación de colocación, y los datos de colocación se asignan al atributo de coincidencia del encabezado de la pila, y se despierta el subproceso 1. Después de despertar el subproceso 1, se obtiene Con el atributo de coincidencia en el encabezado de la pila, puede obtener los datos de colocación.

Estrictamente hablando, no es que la operación put transfiera directamente los datos a la toma, sino que la operación put cambia los datos del encabezado de la pila, de modo que la toma pueda obtener directamente los datos del encabezado de la pila, y el encabezado de la pila es el medio de comunicación entre las operaciones de toma y colocación. .

1.14 Si desea utilizar una cola de tamaño fijo, puede elegir entre varios tipos de colas. ¿Cuál es la diferencia?
Respuesta : LinkedBlockingQueue y ArrayBlockingQueue se pueden usar.

La primera es una lista vinculada, y la segunda es una matriz. Cuando se agrega la lista vinculada, siempre que se establezca la asociación entre los datos nuevos y los datos finales, la posición del índice debe considerarse cuando se agrega la matriz (takeIndex y putIndex se registran por separado Tome el índice de los datos y coloque el índice de los datos), si aumenta a la última posición de la matriz, comenzará a agregarse nuevamente la próxima vez.

1.15 ¿Se puede expandir dinámicamente ArrayBlockingQueue? ¿Qué hacer cuando se usa la última posición de la matriz?
Respuesta : No, aunque la capa inferior de ArrayBlockingQueue es una matriz, no se puede expandir dinámicamente.

Suponiendo que la operación de colocación utiliza la última posición de la matriz, la próxima colocación deberá reiniciarse desde la posición de la matriz 0.

Suponiendo que la operación de toma usa la última posición de la matriz, la próxima toma comenzará desde la posición de la matriz 0 nuevamente.

1.16 ¿Cómo toma y coloca ArrayBlockingQueue encontrar la posición del índice? ¿Se calcula utilizando el algoritmo hash?
Respuesta : ArrayBlockingQueue tiene dos atributos, takeIndex y putIndex, que identifican respectivamente la posición de la siguiente toma y colocación. Cada vez que se completan la toma y la colocación, se incrementarán en uno. Aunque la capa inferior es una matriz, es diferente de HashMap y no se pasa. Calculado por el algoritmo hash.

2 Resumen

Las colas son la base de API complejas, como bloqueos y grupos de subprocesos. Muchos entrevistadores le preguntarán el conocimiento de las colas al preguntar estas API. Si no responde bien, el entrevistador puede pensar que solo ha utilizado bloqueos y grupos de subprocesos. Sin embargo, los principios subyacentes y la implementación no se entienden completamente, por lo que la cola sigue siendo muy importante, pero el código fuente de la cola es más complicado. Se recomienda que pruebe el método de depuración para comprender el código fuente.

Publicado 40 artículos originales · ganado elogios 1 · vistas 4982

Supongo que te gusta

Origin blog.csdn.net/aha_jasper/article/details/105525836
Recomendado
Clasificación