Netease Java back-end cara a cara (un lado)

Este es el lado Java de Netease, y las preguntas son muy básicas.


1. ¿Cómo lidiar con el vencimiento de la sesión?

La caducidad de la sesión generalmente significa que el usuario no realiza ninguna operación durante un período de tiempo, lo que resulta en la invalidación de la sesión. En respuesta a esta situación, se pueden tomar las siguientes medidas:
1. El front-end advierte al usuario que la sesión está a punto de caducar y le recuerda que debe iniciar sesión nuevamente o actualizar la página para mantener la sesión;
2. La parte posterior end agrega un juicio al programa. Si la sesión caduca, devuelve un mensaje de error o pide al usuario que reinicie la sesión. 3.
Agregue un mecanismo para actualizar automáticamente la sesión, como renovar automáticamente la sesión cuando esté a punto de caducar. a través de un temporizador.

 2. ¿Cómo configurar el tiempo de caducidad de redis y cómo renovar el redis?

El comando básico de la prueba:

El tiempo de caducidad de Redis se puede configurar con el comando 'EXPIRE key segundos', donde 'clave' es el nombre de la clave cuyo tiempo de caducidad se debe configurar y 'segundos' es el tiempo de caducidad en segundos.
Por ejemplo: para configurar la clave `mykey` para que caduque después de 10 segundos, el comando es `EXPIRE mykey 10`.

La renovación de Redis puede usar el comando 'EXPIREAT key timestamp', donde 'key' es el nombre de la clave que debe renovarse, y 'timestamp' es la marca de tiempo de renovación en segundos.
Por ejemplo: para extender el tiempo de caducidad de la clave `mykey` a 10 segundos más tarde, el comando es `EXPIREAT mykey 1626914136`, donde `1626914136` es la marca de tiempo después de 10 segundos.

3. ¿Puede Rabbitmq hacer que múltiples consumidores se suscriban a un consumidor? Indique los pasos de implementación.

Sí, los pasos son los siguientes: 

1. Cree una cola de mensajes de RabbitMQ.

2. Cree múltiples consumidores y lea mensajes de la cola respectivamente.

3. Al establecer el tipo de intercambio de la cola de mensajes, vincule varios consumidores al mismo intercambio para que puedan recibir mensajes de la misma cola de mensajes.

4. Cuando se publica un mensaje en el intercambio, se distribuirá a uno de los múltiples consumidores para su procesamiento.

5. Después de procesar el mensaje, el consumidor debe confirmar a la cola que el procesamiento se ha completado, para que RabbitMQ pueda eliminar el mensaje.

4. ¿Cómo trata Rabbitmq los pedidos repetidos?

Si RabbitMQ encuentra pedidos repetidos, puede seguir los pasos a continuación:

1. Verifique la idempotencia de la solicitud de pedido del lado del productor, es decir, juzgue si ya existe la misma solicitud de pedido, si existe, ignore la solicitud directamente y no envíe información a RabbitMQ.

2. Cuando el consumidor recibe la solicitud de pedido, juzga el estado del pedido. Si el pedido ya existe, no lo procesará y devuelve directamente el estado del pedido al productor para informar que el pedido ya existe; si el pedido no existe, luego realice el procesamiento comercial, como la creación de pedidos y la actualización del estado del pedido, y devuelva el estado del pedido al productor para informar que el pedido se creó con éxito.

3. Si necesita garantizar una coherencia sólida en su sistema, puede utilizar bloqueos distribuidos para asegurarse de que solo un consumidor realice operaciones de creación y actualización de pedidos al mismo tiempo, para evitar que varios consumidores procesen la misma solicitud de pedido al mismo tiempo. .

 5. Tipo de datos de Redis, ¿principio de implementación de zest?

Redis admite una variedad de tipos de datos, incluidos cadena (cadena), hash (hash), lista (lista), conjunto (conjunto), conjunto ordenado (zset).

El tipo de datos zset, también conocido como conjunto ordenado, es un tipo especial en Redis que agrega peso al conjunto. Es decir, cada elemento tiene un valor de peso (puntuación) y se ordena de acuerdo con este valor de peso. Al usar una colección ordenada, debe prestar atención a los siguientes puntos:

1. Los elementos de un conjunto ordenado deben ser únicos.
2. El orden de almacenamiento de los elementos se ordena por puntaje de menor a mayor.
3. Los elementos se pueden buscar por rango según la puntuación.

En Redis, la implementación subyacente del tipo de datos zset es una lista de exclusión . La tabla de omisión es una estructura de datos basada en una lista vinculada, y su complejidad de tiempo de consulta e inserción es O (logn), que es altamente eficiente. Cada nodo de la tabla de salto contiene una puntuación y un valor. La puntuación se utiliza para la comparación y clasificación de elementos durante la inserción y la búsqueda, y el valor se utiliza como el valor del elemento.

Cuando el usuario agrega un elemento a zset, Redis insertará el elemento en la posición adecuada en la tabla de salto según la puntuación del elemento. Si tienen la misma puntuación, compare el tamaño del valor y, si siguen siendo los mismos, compare la dirección de almacenamiento del valor.

Cuando el usuario realiza una operación de consulta, Redis realizará una consulta transversal de la tabla de salto de acuerdo con el rango de la puntuación y encontrará elementos que cumplan con las condiciones de la consulta. En la consulta de lista enlazada convencional, la complejidad temporal del recorrido es O(n), mientras que en la consulta de tabla de saltos, dado que los nodos de la lista de saltos no están dispuestos en orden, la complejidad temporal de la consulta puede llegar a O(logn).

6. estrategia de eliminación de redis

 La estrategia de eliminación de Redis puede elegir entre las siguientes:

1. Noeviction (sin estrategia de eliminación): significa que cuando la memoria está llena, la operación de escritura de Redis devolverá directamente el mensaje de error de desbordamiento de memoria. Esta estrategia es adecuada para escenarios en los que no está dispuesto a perder datos y puede tolerar breves interrupciones del servicio.

2. Volatile-lru (política de uso menos reciente) : Indica la eliminación de las claves utilizadas menos recientemente, entre ellas, Volatile significa que solo se configuran para eliminar las claves con tiempo de caducidad, y las claves sin tiempo de caducidad no se eliminan. eliminado Es adecuado para escenarios de almacenamiento en caché.

3. Volatile-ttl (política de tiempo de caducidad) : indica que se eliminan las claves que están a punto de caducar, y Volatile significa que solo se configuran para eliminar las claves con un tiempo de caducidad, y las claves que no tienen un tiempo de caducidad no se eliminan. eliminado, que es adecuado para escenarios de almacenamiento en caché.

4. Volátil-aleatorio (estrategia de eliminación aleatoria) : significa eliminar claves aleatoriamente, pero solo para claves caducadas, y es adecuado para escenarios que no requieren un control preciso de eliminación.

5. Allkeys-lru (política de uso menos reciente) : indica la eliminación de las claves utilizadas menos recientemente, independientemente de si se establece el tiempo de caducidad, y es adecuado para escenarios de almacenamiento en caché.

6. Allkeys-random (estrategia de eliminación aleatoria) : significa eliminar claves aleatoriamente, independientemente de si se establece un tiempo de caducidad, y es adecuado para escenarios que no requieren un control preciso de la eliminación.

Elegir diferentes estrategias de eliminación en diferentes escenarios puede mejorar el rendimiento y la estabilidad de Redis.

7. Motor de almacenamiento MySQL

 El motor de almacenamiento MySQL es una arquitectura modular basada en el sistema de base de datos MySQL, que puede proporcionar diferentes soportes de almacenamiento de datos y lectura y escritura.

El motor de almacenamiento MySQL está integrado cuando se entrega MySQL, incluidos varios tipos de motores de almacenamiento, como MyISAM, InnoDB y MEMORY, y cada motor de almacenamiento tiene sus propias características, ventajas y desventajas únicas.

Por ejemplo, MyISAM es el motor de almacenamiento más utilizado para MySQL, que es adecuado para operaciones de consulta y lectura no interactivas, pero no para operaciones de escritura altamente concurrentes. El motor de almacenamiento InnoDB es adecuado para operaciones de lectura y escritura altamente simultáneas, pero no para procesar operaciones de consulta. El motor de almacenamiento MEMORY puede almacenar datos en caché en la memoria, lo que puede acelerar el acceso, pero si se corta la alimentación o se reinicia el servidor, los datos se perderán.

8. Nivel de aislamiento de transacciones 

Un nivel de aislamiento de transacciones es una característica de un sistema de base de datos que controla la visibilidad y el alcance de la influencia entre múltiples transacciones simultáneas. Los cuatro niveles de aislamiento comunes son:

1. Lectura no confirmada (Lectura no confirmada) : permitir que una transacción lea datos no confirmados puede causar problemas de "lectura sucia".

2. Lectura confirmada (Read Committed) : se requiere una transacción para leer solo los datos confirmados, pero dado que otras transacciones pueden modificar los datos durante la lectura, puede causar problemas de "lectura no repetible".

3. Lectura repetible (Repeatable Read) : cuando se requiere que una transacción lea los mismos datos varias veces durante la ejecución, los resultados obtenidos deben ser consistentes. Por lo tanto, dentro de una transacción, los datos leídos no pueden ser modificados por otras transacciones, y otras transacciones solo pueden modificarse después de confirmar la transacción actual.

4. Serializable (Serializable) : Se requiere que todas las transacciones se ejecuten en secuencia, y se accede a la base de datos en secuencia. Este nivel de aislamiento puede evitar el problema de "lectura fantasma", pero reducirá el rendimiento de la base de datos.

 9. El montón y la pila en jvm también tienen la función de área de método

En la máquina virtual Java, el montón, la pila y el área de métodos son tres áreas que se utilizan para administrar la memoria , y cada área tiene una función diferente.

1. Montón

El montón es un espacio de almacenamiento en la máquina virtual Java para almacenar objetos Java . La memoria del montón se asigna automáticamente cuando se inicia la JVM y se utiliza para almacenar todos los objetos y matrices de Java. Cuando se crea un objeto, asigna un bloque de memoria en el montón y la máquina virtual Java es responsable de recuperar la memoria que ya no se usa. El montón se caracteriza por la memoria asignada dinámicamente, que puede expandirse o reducirse según sea necesario.

2. apilar

La pila es otra área de almacenamiento en la máquina virtual de Java que se utiliza para almacenar variables locales y el entorno de ejecución para llamadas a métodos . Cada vez que se llama a un método, la máquina virtual de Java asigna un nuevo marco de pila para almacenar las variables locales y devolver los valores del método. Cuando el método termina de ejecutarse, se extrae el marco de la pila y otros métodos pueden reutilizar la memoria liberada. La pila se caracteriza por una asignación de memoria rápida, pero su tamaño es fijo y no admite la expansión dinámica.

3. Área de método

El área de métodos también es un área de almacenamiento de la máquina virtual Java, utilizada para almacenar información de clases, constantes, variables estáticas, código compilado por el compilador, etc. El área del método es compartida por todos los subprocesos y no se reciclará en circunstancias normales, y su tamaño también es fijo. La característica del área de métodos es que el contenido de almacenamiento es relativamente estable, pero ocupa una gran cantidad de memoria y requiere una gestión de claves.

 10. La forma de crear hilos

Hay dos formas de crear hilos:

1. Herede la clase Thread y anule el método run(). Cree un objeto de clase de subproceso personalizado y llame al método start() para iniciar el subproceso.

Código de muestra:

class MyThread extends Thread {
    public void run() {
        System.out.println("MyThread is running");
    }
}

public class Main {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start();
    }
}

2. Implemente la interfaz Runnable y reescriba el método run(). Cree un objeto de la clase de implementación de la interfaz Runnable y utilícelo como parámetro para crear un objeto Thread. Llame al método start() del objeto Thread para iniciar el hilo.

Código de muestra:

class MyRunnable implements Runnable {
    public void run() {
        System.out.println("MyRunnable is running");
    }
}

public class Main {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread = new Thread(myRunnable);
        thread.start();
    }
}

11. ¿Qué hacer cuando la cola del grupo de subprocesos está llena?

 Cuando la cola del grupo de subprocesos está llena, generalmente existen los siguientes métodos de procesamiento:

1. Lanzar una excepción : cuando no se puede agregar una tarea a la cola del grupo de subprocesos, se puede lanzar una excepción de tiempo de ejecución para notificar al programa que maneje la excepción.

2. Bloqueo : cuando la cola está llena, las tareas recién enviadas se pueden bloquear y esperar a que se ejecuten las tareas en la cola antes de agregarlas a la cola. Este método es adecuado para situaciones en las que no hay muchas tareas y el tiempo de ejecución de la tarea es corto.

3. Rechazo : cuando la cola está llena, la tarea enviada actualmente puede rechazarse directamente. Este método puede evitar eficazmente que el grupo de subprocesos se colapse debido a demasiadas tareas y garantizar que las tareas posteriores puedan continuar ejecutándose. Se pueden seleccionar diferentes estrategias de rechazo de acuerdo con las necesidades comerciales, como lanzar una excepción directamente o agregar tareas a otras colas para su ejecución.

4. Expansión : cuando la cola del grupo de subprocesos está llena, puede mejorar la eficiencia del procesamiento de tareas aumentando la capacidad de la cola o expandiendo la cantidad de subprocesos en el grupo de subprocesos, evitando así que la cola esté llena.

12. El ciclo de vida de estado en primavera

 En Spring, el ciclo de vida del Bean se puede dividir en las siguientes 8 fases:

1. Cargue el archivo de configuración : el contenedor Spring carga el archivo de configuración de Bean cuando se inicia y lo analiza en la definición de Bean correspondiente (BeanDefinition).

2. Crear una instancia del Bean : el contenedor Spring utiliza el mecanismo de reflexión de Java para crear una instancia del Bean de acuerdo con la definición del Bean.

3. Establecer las propiedades del Bean : el contenedor Spring utiliza el método setter de JavaBean o el mecanismo de reflexión para establecer los valores de las propiedades del Bean.

4. Preprocesamiento de BeanPostProcessor : si el Bean implementa la interfaz BeanPostProcessor, el contenedor Spring llamará automáticamente a su método postProcessBeforeInitialization después de que se crea una instancia del Bean y se establecen las propiedades.

5. Initialize Bean : si Bean implementa la interfaz InitializingBean, el contenedor Spring llamará automáticamente a su método afterPropertiesSet después de que se establezca la propiedad Bean, o utilizará el método de inicialización especificado por el atributo init-method del elemento <bean>.

6. Posprocesamiento de BeanPostProcessor : si el Bean implementa la interfaz BeanPostProcessor, el contenedor Spring llamará automáticamente a su método postProcessAfterInitialization después de inicializar el Bean.

7. Use Bean : en este punto, el Bean se ha ensamblado por completo y puede ser llamado o inyectado en otros objetos por otros objetos.

8. Destruir el Bean : Si el Bean implementa la interfaz del Bean Desechable, el contenedor Spring llamará automáticamente a su método de destrucción cuando se cierre el contenedor, o utilizará el método de destrucción especificado por el atributo destroy-method del elemento <bean>.

Cabe señalar que los primeros 4 pasos del ciclo de vida anterior se producen en la fase de inicio del contenedor o antes de que se obtenga la instancia de Bean por primera vez, y los últimos 4 pasos se producen en la fase de cierre del contenedor o antes de que se destruya la instancia de Bean. .

 13. LeetCode: encuentre la cadena más larga sin repetir subcadenas 3. La subcadena más larga sin repetir caracteres - LeetCode

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        vector<int>f(128, 0);
        int i, j, ans = 0;
        for(i = 0, j = 0; i < s.size(); i ++ ) {
            f[s[i]] ++ ;
            while(f[s[i]] > 1) {
                f[s[j ++ ]] -- ;
            }
            ans = max(ans, i - j + 1);
        }
        return ans;
    }
};

Supongo que te gusta

Origin blog.csdn.net/m0_62600503/article/details/131107299
Recomendado
Clasificación