Colección de entrevistas JavaEE

Colección de entrevistas JavaEE

1. Microservicio SpringCloud

1.1. Centro de registro (Eureka, Zookeeper, Nacos)

El registro tiene dos núcleos, que se dividen en proveedor (proveedor de servicios) y consumidor (consumidor de servicios), también conocido como Web y servicio. El proveedor y el consumidor se registran en el cliente del registro y el nombre del módulo se utiliza al llamar El cliente obtiene la ip y el número de puerto para llamar. Eureka garantiza la disponibilidad, Zookeeper garantiza la coherencia, busque la teoría CAP para obtener más detalles

1.1.1. Eureke

Eureka es actualmente el componente de registro más popular en China. Aunque ha sido descontinuado, su popularidad permanece sin cambios. Aún es recomendado oficialmente por SpringCloud. Clústeres de soporte, el método de implementación es registrarse entre sí.

1.1.1.1. Llamada del módulo Eureka

Eureka usa la llamada remota crp (crp es el método de conexión distribuida de zookeeper, que se usa para llamarlo en China), y el protocolo subyacente es HTTP.

1.1.1.2. Mecanismo de autoprotección y latido del corazón

Una vez iniciada la aplicación, los nodos enviarán latidos a Eureka Server. El período predeterminado es 30 segundos. Si Eureka Server no recibe un latido de un nodo en varios ciclos de latidos, Eureka Server lo enviará desde el registro de servicios. Eliminación del nodo de servicio (predeterminado 90 segundos)

Durante la operación, Eureka Server contará si la tasa de falla de latido es menor al 85% en 15 minutos. Si es menor al 85%, Eureka Server protegerá estas instancias para que estas instancias no caduquen, pero durante el período de protección si El servicio resulta estar anormalmente fuera de línea por parte del proveedor de servicios. En este momento, el consumidor del servicio obtendrá una instancia de servicio no válida y la llamada fallará. Para este problema, el consumidor del servicio debe tener algunos mecanismos de tolerancia a fallas, como reintentar , Disyuntor, etc.

1.1.2. Zookeeper

Es un marco de servicio distribuido y un subproyecto de Apache Hadoop. Se utiliza principalmente para resolver algunos problemas de gestión de datos que se encuentran a menudo en aplicaciones distribuidas, como: servicio de nombres unificado, servicio de sincronización de estado, gestión de clústeres, distribución Gestión de elementos de configuración de aplicaciones, etc.

Dubbo (Ali, similar a SpringCloud) recomienda usar Zookeeper como registro de servicios

1.1.3. Nacos ** (recomendado para aprender o comprender) **

Nacos es un centro de registro lanzado por Ali, e integra las funciones del centro de configuración Config y el bus de mensajes Bus. Tiene un gran potencial y vale la pena aprenderlo usted mismo. Se proporcionan páginas web, lo que simplifica enormemente el costo de aprendizaje.

[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuela. Se recomienda guardar la imagen y subirla directamente (img-L2zas5Az-1600746909872) (archivo: /// C: \ Users \ ADMINI ~ 1 \ AppData \ Local \ Temp \ ksohtml7636 \ wps1.jpg)]

1.2. Cinta de equilibrio de carga

El equilibrio de carga es un algoritmo que se utiliza para resolver todas las solicitudes que una máquina (un proceso) no puede resolver. Por ejemplo, nginx puede usar el equilibrio de carga para distribuir el tráfico, la cinta proporciona equilibrio de carga para los clientes, equilibrio de carga en llamadas de servicio dubbo, etc. El equilibrio de carga se usa en muchos lugares.

Existen varias estrategias de implementación para el equilibrio de carga, las más comunes son:

  1. RoundRobin- (predeterminado)

  2. Aleatorio

  3. Hash consistente (ConsistentHash)

  4. Picadillo

  5. Ponderado

1.3. Invocación declarativa de servicio - Fingir

  1. Fingir puede ocultar la solicitud de Rest y pretender ser un controlador similar a SpringMVC. No necesita empalmar URLs, empalmar parámetros, etc. usted mismo, Feign lo hará todo.

  2. Feign usa Ribbon en la parte inferior, por lo que el equilibrio de carga es compatible de forma predeterminada.

  3. OpenFeign es que springcloud admite anotaciones SpringMVC, como @RequestMapping, etc. sobre la base de Feign. @FeignClient de OpenFeign puede analizar la interfaz bajo la anotación @RequestMapping de SpringMVC y generar clases de implementación a través de un proxy dinámico, implementar el equilibrio de carga en la clase y llamar a otros servicios.

1.4. Pasarela de servicio (Zuul, Zuul2, GetWay)

Pasarela de servicio = reenvío de ruta + filtro

1. Enrutamiento y reenvío: reciba todas las solicitudes externas y reenvíelas a los microservicios de back-end

2. Filtro: se puede completar una serie de funciones transversales en la puerta de enlace de servicio, como verificación de permisos, limitación y monitoreo de corriente, etc.

1.4.1. Zuul

1. Enrutamiento: todas las solicitudes acceden al consumidor a través de zuul

2. Tolerancia a fallas: el cliente no puede llamar al consumidor a través de zuul, use zuul para degradar al consumidor

3. Límite actual: utilice el algoritmo del depósito de tokens para implementar el límite actual de Zuul en el consumidor.

1.4.2. Zuul2

Zuul2 y Zuul son puertas de enlace de servicios desarrolladas por Netflix, pero debido a los problemas de toma de decisiones de la compañía, el personal central que desarrolló Zuul cambió y el desarrollo se retrasó, por lo que actualmente se encuentra en la etapa de prueba de la nueva versión.

1.4.2. GetWay ** (recomendado para aprender o comprender) **

GetWay es un componente de puerta de enlace de servicio lanzado oficialmente por SpringCloud. Debido al aplazamiento de Zuul2, SpringCloud decidió oficialmente desarrollar su propio componente de puerta de enlace de servicio. Hasta ahora, GetWay resultó ser muy popular en países extranjeros, pero Zuul se utiliza básicamente en China. Se implementan GetWay y Zuul2, modelo asincrónico sin bloqueo.

1.5. Degradación del servicio (Hystrix, Sentinel)

1.5.1. Hystrix

1. Bajar de categoría

Cuando el proveedor de servicios no puede llamar al consumidor del servicio, utilice Hystrix para degradar al consumidor del servicio y devolver los datos inferiores.

2. Fusible

Cuando la tasa de falla, el grupo de subprocesos y el semáforo alcanzan el umbral, la degradación se activa automáticamente. La degradación activada por el fusible probará si el servicio se restablece después de un tiempo específico. (La siguiente solicitud después de 5 segundos de forma predeterminada probará si el servicio se restaura)

1.5.2. Sentinel ** (recomendado para aprender o comprender) **

Sentinel es una nueva generación de componentes degradados de disyuntores lanzados por Ali. No requiere mucha configuración cuando se usa como Hystrix.

Sentinel es un componente separado, que puede ser una configuración unificada independiente, orientada a la página directa y detallada, y proporciona un conjunto de páginas web para implementar operaciones como control de flujo, velocidad, degradación y fusión.

[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuela. Se recomienda guardar la imagen y cargarla directamente (img-9DZM8JcX-1600746909878) (archivo: /// C: \ Users \ ADMINI ~ 1 \ AppData \ Local \ Temp \ ksohtml7636 \ wps2.jpg)]

1.6. Configuración del centro de configuración y bus de bus de mensajes

Centro de configuración de configuración: se utiliza para administrar de forma centralizada archivos de configuración

Bus de mensajes de bus: se utiliza para actualizar el archivo de configuración sin reiniciar

Proceso de trabajo:

  1. Primero envíe el archivo de configuración al GitHub remoto

  2. Configurar la dirección de GitHub en el cliente de configuración

  3. Use cartero para enviar una solicitud de publicación y notifique al cliente de configuración para que extraiga el archivo de configuración

  4. Después de descargar el archivo de configuración, envíe un mensaje a la cola de MQ

  5. El bus escucha la cola MQ después de recibir el mensaje

  6. Bus envía mensajes MQ para notificar a los módulos correspondientes

  7. Después de que el módulo reciba el mensaje, vaya al cliente de configuración para obtener el archivo de configuración y actualizarlo

2. Multihilo

El subproceso múltiple es muy común en los proyectos. Por ejemplo, para leer de manera eficiente un archivo txt grande, primero divida el archivo txt y luego use el subproceso múltiple para leer cada fragmento y luego combínelos, que es lo más eficiente.

2.1. Implementación multiproceso

  1. Heredar la clase Thread:

Simplemente anule el método de ejecución. La desventaja es que Java es de herencia única y múltiples implementaciones. En este caso, la clase no puede heredar otras clases, y generalmente no se recomienda.

  1. Implemente la interfaz Runnable:

Para resolver el problema de herencia única de la clase Thread, se pueden realizar múltiples subprocesos. La desventaja es que no hay valor de retorno y el resultado no se puede recibir y solo se puede anular.

  1. Implemente la interfaz invocable:

Java5 proporciona la interfaz Future para representar el valor de retorno del método call () en la interfaz Callable y proporciona una clase de implementación FutureTask para la interfaz Future.

  1. Obtenido del grupo de subprocesos:

Utilice Ejecutores para crear subprocesos y llamar a subprocesos, que pueden tener valores de retorno. Cuando se utilizan varios subprocesos a gran escala, se recomienda utilizar grupos de subprocesos, y los subprocesos deben cerrarse después de su uso.

2.2. Estado del hilo

Nuevo estado:

Después de crear un objeto hilo usando la nueva palabra clave y la clase Thread o sus subclases, el objeto hilo está en un estado recién creado. Permanece en este estado hasta que el programa inicia () el hilo.

Estado listo:

Cuando el objeto del hilo llama al método start (), el hilo entra en el estado listo. Los subprocesos en estado listo están en la cola lista y esperan la programación del planificador de subprocesos en la JVM.

Estado operativo:

Si el subproceso en el estado listo adquiere recursos de la CPU, puede ejecutar run () y el subproceso ahora está en el estado de ejecución. El hilo en el estado de ejecución es el más complicado y puede bloquearse, estar listo y muerto.

Estado bloqueado:

Si un hilo ejecuta sleep (dormir), suspender (suspender) y otros métodos, después de perder los recursos ocupados, el hilo entra en estado de bloqueo desde el estado de ejecución. El estado listo se puede volver a ingresar después de que finalice el tiempo de suspensión o se obtengan los recursos del dispositivo.

Estado de muerte:

Cuando un subproceso en el estado de ejecución completa su tarea u ocurren otras condiciones de terminación, el subproceso cambia al estado de terminación.

3. Bloqueo de sincronización

3.1. La diferencia entre Synchronized y Lock (ReentrantLock)

Synchronized es un modificador en java. Puede modificar clases, métodos y bloques de código. No necesita liberar manualmente el bloqueo. Si ocurre una excepción, el bloqueo se liberará automáticamente sin causar un interbloqueo. La operación es simple.

El bloqueo solo puede bloquear el bloque de código y necesita liberarlo manualmente. Si no se llama al método de desbloqueo para liberar el bloqueo, causará un interbloqueo y proporciona algunos métodos de operación para obtener fácilmente la información del bloqueo.

4. Base de datos MySQL

4.1. La diferencia entre InnoDB y MyISAM

InnoDB:

  1. Adecuado para agregar, eliminar y modificar

  2. Debe tener una clave principal

  3. Asuntos de apoyo

  4. Índice agrupado

  5. La granularidad mínima de bloqueo es bloqueo a nivel de fila

  6. Se cambió al motor de almacenamiento predeterminado después de MySQL-5.5.

MyISAM:

  1. Adecuado para consulta

  2. Índice no agrupado

  3. Recuperación lenta después de un bloqueo del sistema

  4. La granularidad mínima de bloqueo es bloqueo a nivel de tabla

4.2. Orden de ejecución de la instrucción SQL

desde-en-unirse-donde-grupo al-tener-seleccionar-distinto-orden por-límite

Tabla de búsqueda-filtrado-conexión-filtrado-agrupación-filtrado-columna especificada deduplicación-ordenación-paginación

4.3. Estructura de árbol B +, con enlace al sitio web de aprendizaje

https://www.cs.usfca.edu/~galles/visualization/Algorithms.html

Árbol binario:

El árbol binario es la estructura de árbol más básica, según el primer valor, el pequeño se coloca a la izquierda y el grande a la derecha.

Árbol rojo-negro:

El árbol rojo-negro se realiza sobre la base del árbol binario, y el ajuste del equilibrio dinámico no hará que la cadena sea demasiado larga.

Árbol B:

El árbol B se basa en el árbol rojo-negro, que se puede escalar horizontalmente en los nodos, y cada nodo se puede montar con datos de valores clave, lo que puede reducir el número de consultas de E / S

Árbol B +:

El árbol B + es una estructura de datos exclusiva desarrollada por MySQL. Basado en el árbol B, se corta. Los datos clave-valor en el árbol B solo retienen la clave y solo tienen el clave-valor en el siguiente nodo. Datos, la clave es la clave principal, el valor se determina en función de si la estructura de almacenamiento es InnoDB o MyISAM, y el valor es una dirección de disco o datos

5. JVM y GC

5.1. Modelo de memoria JVM

[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuelas. Se recomienda guardar la imagen y subirla directamente (img-XNK7Kuig-1600746909881) (archivo: /// C: \ Users \ ADMINI ~ 1 \ AppData \ Local \ Temp \ ksohtml7636 \ wps3.png)]

JVM: https: //www.bilibili.com/video/BV11J411N7Tg? From = search & seid = 11648229642537222949

5.1.1. Contador de programa (hilo privado)

Registra la secuencia de comandos del programa y el número de línea de código de bytes ejecutado por el hilo actual. Cada hilo tiene un contador de programa independiente. Este tipo de memoria también se llama memoria "privada de hilo".

5.1.2. Pila de máquina virtual JAVA (hilo privado) (pila)

Se almacenan variables y objetos declarados. Cuando se ejecuta cada método, también se crea un marco de pila, que almacena variables locales, operandos, enlaces dinámicos y direcciones de retorno de métodos. Cada método desde la invocación hasta la finalización de la ejecución corresponde al empuje y al estallido de un marco de pila en la pila de la máquina virtual. En términos generales, la pila generalmente se refiere a la parte de la variable local en la pila de la máquina virtual.

[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuela. Se recomienda guardar la imagen y cargarla directamente (img-HSbh8nsT-1600746909885) (archivo: /// C: \ Users \ ADMINI ~ 1 \ AppData \ Local \ Temp \ ksohtml7636 \ wps4.png)]

Marco de pila actual: representa el método que se está ejecutando actualmente, almacenando las variables, objetos, comandos de operación y otros datos relacionados y comportamientos de operación del método actual.

5.1.2.1. Tabla de variables locales

Almacene varios tipos de datos básicos, tipos de referencia de objeto y tipos returnAddress (apuntando a la dirección de una instrucción de código de bytes: dirección de retorno de función) que se pueden conocer en tiempo de compilación.
Largo y doble ocupan dos ranuras de control variable local.
El espacio de memoria requerido por la tabla de variables locales se determina en el momento de la compilación Al ingresar un método, el control de la variable local que el método necesita asignar en el marco de la pila está completamente determinado y el tamaño no se puede cambiar dinámicamente.

5.1.2.2. Pila de operandos

LIFO último en entrar, primero en salir, la profundidad máxima está determinada por el período de compilación. El marco de la pila se acaba de crear, la pila de operandos está vacía. Al realizar operaciones de método, la pila de operandos se usa para almacenar las constantes o variables copiadas por la JVM de la tabla de variables locales, proporcionar extracción y enviar los resultados a la pila, y también se usa para almacenar las llamadas requeridas por el método Parámetros y resultados devueltos por el método de recepción.
La pila de operandos puede almacenar un valor de cualquier tipo de datos definido en el jvm.
En cualquier momento, la pila de operandos tiene una profundidad de pila fija, excepto long y double, los tipos básicos ocupan dos profundidades y los demás ocupan una profundidad.

5.1.2.3. Enlace dinámico

Cada marco de pila contiene una referencia al método al que pertenece el marco de pila en el grupo de constantes de tiempo de ejecución. Esta referencia se mantiene para admitir la conexión dinámica durante la invocación del método. Hay una gran cantidad de referencias a símbolos en el grupo constante del archivo Class, y la instrucción de llamada al método en el código de bytes toma la referencia del símbolo que apunta al método en el grupo constante como parámetro. Algunas de estas referencias de símbolos se convertirán en referencias directas (como dominios finales, estáticos, etc.) durante la etapa de carga de clases o la primera vez que se utilicen, lo que se denomina resolución estática, y la otra parte se convertirá en referencias directas durante cada ejecución. La pieza se llama conexión dinámica.

5.1.2.4. Exportación de métodos

Cuando se ejecuta un método, hay dos formas de salir del método: el motor de ejecución encuentra una instrucción de código de bytes devuelta por cualquier método o encuentra una excepción, y la excepción no se maneja en el cuerpo del método. Independientemente del método de salida que se utilice, después de que el método salga, debe volver al lugar donde se llamó al método antes de que el programa pueda continuar. Cuando el método regrese, es posible que deba guardar cierta información en el marco de la pila para ayudar a restaurar el estado de ejecución de su método superior. En términos generales, cuando el método sale normalmente, el valor del contador de PC de la persona que llama se puede utilizar como dirección de retorno. Es probable que este valor del contador se almacene en el marco de pila. Cuando el método sale de forma anormal, la dirección de retorno la determina el manejador de excepciones. , Esta parte de la información generalmente no se guarda en el marco de pila.
El proceso de salida del método es en realidad equivalente a hacer estallar el marco de pila actual, por lo que las operaciones que se pueden realizar al salir son: restaurar la tabla de variables locales y la pila de operandos del método superior, y si hay un valor de retorno, empujarlo al marco de pila del llamador En la pila de operandos, ajuste el valor del contador de la PC para que apunte a una instrucción después de la instrucción de llamada al método.

5.1.3. Pila de métodos locales (entender)

Utilice principalmente llamadas de hardware de computadora, como impresoras, teclados, ratones y otros dispositivos de hardware, que han sido abandonados El sistema ejecuta comandos de hardware en lugar de operaciones directas.

5.1.4. Heap (intercambio de hilos)

Un área de memoria compartida por todos los subprocesos, creada cuando se inicia la máquina virtual y utilizada para almacenar instancias de objetos. El par se puede implementar como extensible (controlado por -Xmx y -Xms), que también es la dirección principal de la recuperación de GC.

La memoria de pila generalmente se divide en generación joven, generación anterior y generación permanente.Después de JDK1.8, se usa el metaespacio en lugar de la generación permanente, porque Oracle reemplazó oficialmente a otra JVM desarrollada de acuerdo con la convención JVM.

5.1.5. Área de métodos (intercambio de hilos)

Un área de memoria compartida por todos los hilos del método.
Se utiliza para almacenar información de clase, constantes, variables estáticas, etc. que han sido cargadas por la máquina virtual.
El objetivo de recuperación de memoria en esta área es principalmente para la recuperación del grupo constante y la descarga del tipo de pila.

5.2. Recolector de basura de GC

GC: https://www.bilibili.com/video/BV154411r7GP?p=7

5.2.1. Método de recuento de referencias

Se utiliza un contador para registrar el uso de cada objeto. Los objetos con 0 tiempos de uso se recuperan durante la GC y los datos se almacenan en la generación anterior cuando el tiempo de uso llega a 15.

Características: El contador debe mantenerse y el uso del contador también consumirá una cierta cantidad de recursos. JVM generalmente no usa este método.

5.2.2. Copiar algoritmo

Abra dos espacios en la memoria, primero almacene los datos en un lado y copie los datos supervivientes en el otro lado de la memoria durante la GC y agregue la edad del objeto + 1. Si llega a 15, el objeto se almacenará en la antigüedad. Después de que el objeto se haya copiado Luego vacíe la memoria.

Características: Duplique el espacio de memoria requerido.

Este algoritmo se utiliza en la generación joven, porque el algoritmo de replicación es adecuado para la generación joven con una tasa de supervivencia baja.

5.2.3. Eliminación de marcas

Dividido en dos pasos

El primer paso es marcar: comience a escanear desde la colección raíz y marque los objetos supervivientes

El segundo paso es limpiar: escanee todo el espacio de la memoria, recupere los objetos sin marcar

Características: Los dos escaneos requieren mucho tiempo y causan fragmentación de la memoria y no se necesita espacio adicional. Sin embargo, el algoritmo suspenderá toda la aplicación; de lo contrario, habrá dos escaneos y el objeto llamado se juzgará incorrectamente.

5.2.4. Compresión de marcadores

Dividido en dos pasos

El primer paso es marcar: igual que marcar claro, marcar primero y luego borrar

El segundo paso de la compresión: escanee de nuevo y deslice los objetos supervivientes a una sección

Características: No hay fragmentación de la memoria y se requiere el costo de mover objetos.

Desventajas de la fragmentación de la memoria: ocupará toda la memoria de forma irregular, por ejemplo, cuando se necesita crear un arreglo, porque el arreglo requiere un uso continuo del espacio, será muy problemático si hay fragmentación de la memoria.

Optimización: para reducir el costo de mudanza, puede diseñar la operación de compresión cuando el GC es un cierto número de veces.

5.2.5. Algoritmo óptimo

Marcar como claro *

Dividido en dos pasos

El primer paso es marcar: comience a escanear desde la colección raíz y marque los objetos supervivientes

El segundo paso es limpiar: escanee todo el espacio de la memoria, recupere los objetos sin marcar

Características: Los dos escaneos requieren mucho tiempo y causan fragmentación de la memoria y no se necesita espacio adicional. Sin embargo, el algoritmo suspenderá toda la aplicación; de lo contrario, habrá dos escaneos y el objeto llamado se juzgará incorrectamente.

5.2.4. Compresión de marcadores

Dividido en dos pasos

El primer paso es marcar: igual que marcar claro, marcar primero y luego borrar

El segundo paso de la compresión: escanee de nuevo y deslice los objetos supervivientes a una sección

Características: No hay fragmentación de la memoria y se requiere el costo de mover objetos.

Desventajas de la fragmentación de la memoria: ocupará toda la memoria de forma irregular, por ejemplo, cuando se necesita crear un arreglo, porque el arreglo requiere un uso continuo del espacio, será muy problemático si hay fragmentación de la memoria.

Optimización: para reducir el costo de mudanza, puede diseñar la operación de compresión cuando el GC es un cierto número de veces.

5.2.5. Algoritmo óptimo

No existe un algoritmo óptimo, solo el algoritmo más adecuado. El algoritmo óptimo se selecciona de acuerdo con factores como la eficiencia de la memoria, la limpieza de la memoria y la utilización de la memoria.

Supongo que te gusta

Origin blog.csdn.net/zhang_yuanbai/article/details/108728459
Recomendado
Clasificación