Preguntas de la entrevista de Complete Works of Java (9)

Preguntas de la entrevista de Complete Works of Java (9)

Baiyu es jaja

80. ¿Qué es el ACID de una transacción?

responder:

  • Atómico: Todas las operaciones de la transacción se realizan o no se realizan. El fallo de cualquier operación provocará el fallo de toda la transacción;
  • Consistente: el estado del sistema es consistente después de que finaliza la transacción;
  • Aislamiento (aislado): las transacciones ejecutadas simultáneamente no pueden ver el estado intermedio de las demás;
  • Durable: los cambios realizados después de que se complete la transacción se mantendrán, incluso si ocurre una falla catastrófica. Los datos se pueden reconstruir después de que ocurra una falla mediante el registro y la copia de seguridad sincrónica.

Suplemento: Respecto a los asuntos, la probabilidad de que te pregunten en una entrevista es muy alta, y hay muchas preguntas que se pueden hacer. Lo primero que debe saber es que las transacciones solo se requieren cuando hay accesos de datos concurrentes. Cuando varias transacciones acceden a los mismos datos, puede haber cinco tipos de problemas, incluidos tres tipos de problemas de lectura de datos (lecturas sucias, lecturas no repetibles y lecturas fantasmas) y dos tipos de problemas de actualización de datos (actualizaciones faltantes tipo 1 y tipo 2 Actualización perdida).

Lectura sucia: la Transacción A lee los datos no confirmados de la Transacción B y opera sobre esta base, y la Transacción B realiza una reversión, entonces los datos leídos por A son datos sucios.

Preguntas de la entrevista de Complete Works of Java (9)

Lectura irrepetible: la transacción A vuelve a leer los datos leídos anteriormente y encuentra que los datos han sido modificados por otra transacción B confirmada.

Preguntas de la entrevista de Complete Works of Java (9)

Lectura fantasma: Transacción A vuelve a ejecutar una consulta y devuelve una serie de filas que cumplen las condiciones de la consulta.Se encuentra que las filas enviadas por la transacción B están insertadas.
Estadísticas de tiempo importe transacción A transferir transacción B
Preguntas de la entrevista de Complete Works of Java (9)
tipo 1 actualización perdida: cuando se cancela la transacción A, se sobrescriben los datos actualizados de la transacción B que se ha enviado.
Preguntas de la entrevista de Complete Works of Java (9)
El segundo tipo de actualización perdida: la transacción A sobrescribe los datos que la transacción B ha comprometido, lo que hace que se pierda la operación de la transacción B.
Preguntas de la entrevista de Complete Works of Java (9)

Los problemas causados ​​por el acceso concurrente a los datos pueden estar permitidos en algunos escenarios, pero pueden ser fatales en algunos escenarios. La base de datos generalmente resuelve el problema del acceso concurrente a los datos a través de un mecanismo de bloqueo, que se puede dividir en bloqueos a nivel de tabla y bloqueos de acuerdo con diferentes objetos de bloqueo. Los bloqueos de nivel de fila se pueden dividir en bloqueos compartidos y bloqueos exclusivos de acuerdo con la relación de bloqueo de las transacciones simultáneas. Puede verificar la información para comprender el contenido específico.
Es muy problemático usar bloqueos directamente. Por esta razón, la base de datos proporciona a los usuarios un mecanismo de bloqueo automático. Siempre que el usuario especifique el nivel de aislamiento de la transacción de la sesión, la base de datos analizará las declaraciones SQL y agregará los bloqueos adecuados a los recursos a los que accede la transacción. Además, la base de datos También mantendrá estos bloqueos para mejorar el rendimiento del sistema a través de varios medios, que son transparentes para el usuario (es decir, no es necesario que entiendas, de hecho no lo sé). El estándar ANSI / ISO SQL 92 define 4 niveles de niveles de aislamiento de transacciones, como se muestra en la siguiente tabla:
Preguntas de la entrevista de Complete Works of Java (9)

Cabe señalar que el nivel de aislamiento de la transacción y la concurrencia del acceso a los datos son opuestos, cuanto mayor es el nivel de aislamiento de la transacción, peor es la concurrencia. Por lo tanto, el nivel apropiado de aislamiento de transacciones debe determinarse de acuerdo con la aplicación específica No existe un principio universal en este lugar.

81. ¿Cómo gestionar las transacciones en JDBC?

Respuesta: Connection proporciona un método de procesamiento de transacciones, al llamar a setAutoCommit (falso), puede configurar para confirmar manualmente la transacción; cuando la transacción se complete, use commit () para confirmar explícitamente la transacción; si ocurre una excepción durante el procesamiento de la transacción, use rollback () para realizar la transacción Retroceder. Además, el concepto de Savepoint se introdujo desde JDBC 3.0, lo que le permite establecer un punto de guardado a través del código y revertir la transacción al punto de guardado especificado.
Preguntas de la entrevista de Complete Works of Java (9)

82. ¿Puede JDBC manejar Blob y Clob?

Respuesta: Blob se refiere a un objeto grande binario y Clob se refiere a un objeto grande de caracteres, por lo que Blob está diseñado para almacenar datos binarios grandes y Clob es para almacenar datos de texto grandes Y diseñado. PreparedStatement y ResultSet de JDBC proporcionan los métodos correspondientes para admitir operaciones Blob y Clob. El siguiente código muestra cómo usar JDBC para operar LOB:
Tome la base de datos MySQL como ejemplo, cree una tabla de usuario con tres campos, incluyendo ID, nombre y foto. La declaración de la tabla es la siguiente:


create table tb_user
(id int primary key auto_increment,
name varchar(20) unique not null,
photo longblob );

El siguiente código Java inserta un registro en la base de datos:


import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
class JdbcLobTest {
    public static void main(String[] args) {
        Connection con = null;
        try {
            // 1. 加载驱动(Java6以上版本可以省略)
            Class.forName("com.mysql.jdbc.Driver");
            // 2. 建立连接
            con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "123456");
            // 3. 创建语句对象
            PreparedStatement ps = con.prepareStatement("insert into tb_user values (default, ?, ?)");
            ps.setString(1, "骆昊");              // 将SQL语句中第一个占位符换成字符串
            try (InputStream in = new FileInputStream("test.jpg")) {    // Java 7的TWR
                ps.setBinaryStream(2, in);      // 将SQL语句中第二个占位符换成二进制流
                // 4. 发出SQL语句获得受影响行数                System.out.println(ps.executeUpdate() == 1 ? "插入成功" : "插入失败");
            } catch(IOException e) {
                System.out.println("读取照片失败!");
            }
        } catch (ClassNotFoundException | SQLException e) {     // Java 7的多异常捕获
            e.printStackTrace();
        } finally { // 释放外部资源的代码都应当放在finally中保证其能够得到执行
            try {
                if(con != null && !con.isClosed()) {                    con.close();    // 5. 释放数据库连接 
                    con = null;     // 指示垃圾回收器可以回收该对象
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

83. Describa brevemente las expresiones regulares y sus usos.

Respuesta: Al escribir programas que procesan cadenas, a menudo es necesario encontrar cadenas que cumplan con ciertas reglas complejas. Las expresiones regulares son herramientas que se utilizan para describir estas reglas. En otras palabras, las expresiones regulares son códigos que registran reglas de texto.

Nota: En los primeros días del nacimiento de la computadora, casi toda la información procesada eran valores numéricos, pero el tiempo ha pasado. Hoy usamos computadoras para procesar información con más frecuencia que valores numéricos pero cadenas. Las expresiones regulares son las más poderosas para el procesamiento y la comparación de cadenas. Herramientas, la mayoría de los idiomas brindan soporte para expresiones regulares.

84. ¿Cómo soporta Java las operaciones de expresiones regulares?

Respuesta: La clase String en Java proporciona métodos para admitir operaciones de expresión regular, incluidas coincidencias (), replaceAll (), replaceFirst (), split (). Además, la clase Pattern se puede utilizar para representar objetos de expresión regular en Java. Proporciona una API enriquecida para varias operaciones de expresión regular. Consulte el código de las preguntas de la entrevista a continuación.

Preguntas de la entrevista: -Si desea interceptar la cadena antes del primer paréntesis izquierdo en inglés de la cadena, por ejemplo: Beijing (Distrito de Chaoyang) (Distrito de Xicheng) (Distrito de Haidian), el resultado de la interceptación es: Beijing, entonces la expresión regular ¿cómo escribir?


import java.util.regex.Matcher;import java.util.regex.Pattern;
class RegExpTest {
    public static void main(String[] args) {
        String str = "北京市(朝阳区)(西城区)(海淀区)";
        Pattern p = Pattern.compile(".*?(?=\\()");
        Matcher m = p.matcher(str);
        if(m.find()) {
            System.out.println(m.group());
        }
    }
}
  • 14

Nota: En las expresiones regulares anteriores se utilizan las coincidencias perezosas y anticipar. Si no está seguro de estos contenidos, le recomiendo leer el conocido "Tutorial de 30 minutos de expresiones regulares" en Internet.

85. ¿Cuáles son las formas de obtener un objeto de clase?

responder:

  • Método 1: Type.class, por ejemplo: String.class
  • Método 2: Object.getClass (), por ejemplo: "hola" .getClass ()
  • 方法 3 : Class.forName () , 例如 : Class.forName ("java.lang.String")

    86. ¿Cómo crear objetos mediante la reflexión?

    responder:

  • Método 1: llamar al método newInstance () a través del objeto de clase, por ejemplo: String.class.newInstance ()
  • Método 2: Obtenga el objeto constructor (Constructor) a través del método getConstructor () o getDeclaredConstructor () del objeto de clase y llame a su método newInstance () para crear el objeto, por ejemplo: String.class.getConstructor (String.class) .newInstance ("Hola" );

    87. ¿Cómo obtener y establecer el valor del campo privado de un objeto a través de la reflexión?

    Respuesta: Puede usar el método getDeclaredField () del objeto de clase para configurar el objeto Field, y luego configurarlo para que sea accesible a través de setAccessible (verdadero) del objeto field, y luego puede obtener / establecer el valor del campo a través del método get / set Arriba. El siguiente código implementa una clase de herramienta reflectante. Los dos métodos estáticos se utilizan para obtener y establecer el valor de un campo privado. El campo puede ser un tipo básico o un tipo de objeto y admite operaciones de objetos de varios niveles, como ReflectionUtil.get ( dog, "owner.car.engine.id"); Se puede obtener el número de identificación del motor del automóvil del propietario del objeto perro.


import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
/** * 反射工具类 * @author 骆昊 * */
public class ReflectionUtil {
    private ReflectionUtil() {
        throw new AssertionError();
    }
    /**     * 通过反射取对象指定字段(属性)的值     * @param target 目标对象     * @param fieldName 字段的名字     * @throws 如果取不到对象指定字段的值则抛出异常     * @return 字段的值     */
    public static Object getValue(Object target, String fieldName) {
        Class<?> clazz = target.getClass();
        String[] fs = fieldName.split("\\.");
        try {
            for(int i = 0; i < fs.length - 1; i++) {
                Field f = clazz.getDeclaredField(fs[i]);
                f.setAccessible(true);
                target = f.get(target);
                clazz = target.getClass();
            }
            Field f = clazz.getDeclaredField(fs[fs.length - 1]);
            f.setAccessible(true);
            return f.get(target);
        }
        catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**     * 通过反射给对象的指定字段赋值     * @param target 目标对象     * @param fieldName 字段的名称     * @param value 值     */
    public static void setValue(Object target, String fieldName, Object value) {
        Class<?> clazz = target.getClass();
        String[] fs = fieldName.split("\\.");
        try {
            for(int i = 0; i < fs.length - 1; i++) {
                Field f = clazz.getDeclaredField(fs[i]);
                f.setAccessible(true);
                Object val = f.get(target);
                if(val == null) {
                    Constructor<?> c = f.getType().getDeclaredConstructor();
                    c.setAccessible(true);
                    val = c.newInstance();
                    f.set(target, val);
                }
                target = val;
                clazz = target.getClass();
            }
            Field f = clazz.getDeclaredField(fs[fs.length - 1]);
            f.setAccessible(true);
            f.set(target, value);
        }
        catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

88. ¿Cómo llamar al método de un objeto a través de la reflexión?

Respuesta: consulte el código a continuación:


import java.lang.reflect.Method;
class MethodInvokeTest {
    public static void main(String[] args) throws Exception {
        String str = "hello";
        Method m = str.getClass().getMethod("toUpperCase");
        System.out.println(m.invoke(str));  // HELLO
    }
}

89. Describa brevemente los "seis principios y una regla" orientados a objetos.

responder:

  • Principio de responsabilidad única: una clase solo hace lo que debe hacer. (El principio de responsabilidad única quiere expresar "alta cohesión", y el principio fundamental de la escritura de código es solo seis palabras "alta cohesión, bajo acoplamiento", al igual que la idea central del Libro del girasol o la espada de los espíritus malignos es "deseo". Para practicar este ejercicio, primero debes venir del palacio ". La llamada alta cohesión significa que un módulo de código solo completa una función. En la orientación a objetos, si solo una clase puede hacer lo que debe hacer, no involucra áreas que no tienen nada que ver con ella. Practicando el principio de alta cohesión, esta clase tiene una sola responsabilidad. Todos conocemos un dicho llamado "Por el enfoque, tan profesional", si un objeto asume demasiadas responsabilidades, entonces está condenado a no hacer nada. Este mundo Cualquier cosa buena de lo anterior tiene dos características. Una es que tiene una sola función. Una buena cámara definitivamente no es el tipo de máquina que se vende en la compra de TV. Tiene más de cien funciones. Básicamente solo puede tomar fotografías; la otra es modular. Una buena bicicleta es una bicicleta ensamblada. Desde el amortiguador, los frenos hasta la transmisión, todas las piezas se pueden desmontar y volver a montar. Una buena raqueta de ping pong no es una raqueta terminada. Debe ser la placa base y la goma que se puedan desmontar y montar por sí mismos. , Un buen sistema de software, cada módulo funcional en él también debe usarse fácilmente en otros sistemas, para lograr el objetivo de la reutilización del software).
  • Principio de apertura y cierre: La entidad de software debe estar abierta para extensión y cerrada para modificación. (En un estado ideal, cuando necesitamos agregar nuevas funciones a un sistema de software, solo necesitamos derivar algunas clases nuevas del sistema original, sin modificar ninguna línea de código original. Hay dos formas de abrir y cerrar. Puntos clave: ①La clave es la abstracción. Si no hay una clase abstracta o un sistema de interfaz en un sistema, no habrá un punto de extensión; nca Encapsular la variabilidad, encapsular varios factores variables en el sistema en una estructura de herencia, si se mezclan múltiples factores variables Juntos, el sistema se volverá complejo y caótico. Si no sabe cómo encapsular la variabilidad, puede consultar el capítulo sobre el patrón de puente en el libro "Elaboración de patrones de diseño").
  • Confíe en el principio de inversión: programación orientada a interfaces. (El principio es sencillo y específico. Al declarar tipos de parámetros de métodos, tipos de retorno de métodos y tipos de referencias de variables, utilice tipos abstractos tanto como sea posible en lugar de tipos concretos, porque los tipos abstractos pueden ser utilizados por cualquiera de sus subtipos. Para la sustitución, consulte el Principio de sustitución de Richter a continuación.)
    Principio de sustitución de Richter: puede reemplazar el tipo principal con un subtipo en cualquier momento. (Con respecto a la descripción del principio de sustitución de Richter, la descripción de la Sra. Barbara Liskov es mucho más complicada que esto, pero en términos simples, el subtipo se puede usar donde sea que se pueda usar el supertipo. El principio de sustitución de Richter puede verificar si la relación de herencia es razonable. Si una relación de herencia viola el principio de sustitución de Richter, entonces la relación de herencia debe ser incorrecta y el código debe ser refactorizado. Por ejemplo, dejar que los gatos hereden de los perros, o que los perros hereden de los gatos, o dejar que los cuadrados hereden de los rectángulos son relaciones de herencia incorrectas. , Porque puede encontrar fácilmente escenas que violan el principio de sustitución de Richter. Cabe señalar que la clase secundaria debe aumentar la capacidad de la clase principal en lugar de reducir la capacidad de la clase principal, porque la clase secundaria tiene más capacidades que la clase principal. Por supuesto, no hay problema en usar el objeto como un objeto menos capaz).
  • Principio de aislamiento de la interfaz: la interfaz debe ser pequeña y especializada, nunca grande y completa. (La interfaz hinchada contamina la interfaz. Dado que la interfaz expresa la capacidad, una interfaz solo debe describir un tipo de capacidad, y la interfaz también debe ser muy cohesiva. Por ejemplo, Qinqi, caligrafía y pintura deben diseñarse como cuatro interfaces en lugar de Debe diseñarse en cuatro métodos en una interfaz, porque si está diseñado en cuatro métodos en una interfaz, entonces esta interfaz es difícil de usar. Después de todo, todavía hay algunas personas que dominan los cuatro de piano, ajedrez, caligrafía y pintura, y si está diseñado en cuatro interfaces , Algunos elementos implementarán varias interfaces. De esta manera, la posibilidad de que cada interfaz sea reutilizada es muy alta. Las interfaces en Java representan capacidades, convenciones y roles. Si la interfaz se puede usar correctamente debe ser un nivel de programación. Marca importante.)
  • Principio de reutilización de agregación sintética: Priorizar el uso de códigos de reutilización de agregación o relación sintética. (Reutilizar el código a través de la herencia es lo más abusado en la programación orientada a objetos, porque todos los libros de texto promueven la herencia sin excepción, lo que confunde a los principiantes. Hay tres tipos de clases. Las relaciones, la relación Is-A, la relación Has-A y la relación Use-A, respectivamente, representan herencia, asociación y dependencia. Entre ellas, las relaciones de asociación se pueden dividir en asociación, agregación y síntesis según la fuerza de su asociación, pero todas son Relación Has-A, el principio de reutilización de agregación compuesta quiere expresar que se da prioridad a la relación Has-A en lugar de la relación Is-A para reutilizar el código. La razón se puede encontrar en Baidu por 10,000 razones. Es necesario explicar que incluso en También hay muchos ejemplos de abuso de herencia en la API de Java. Por ejemplo, la clase Properties hereda la clase Hashtable y la clase Stack hereda la clase Vector. Estas herencias son obviamente incorrectas. Un mejor enfoque es colocar un miembro de tipo Hashtable en la clase Properties y Establezca sus claves y valores en cadenas para almacenar datos, y el diseño de la clase Stack también debe colocar un objeto Vector en la clase Stack para almacenar datos. Recuerde: no herede la clase de herramienta en ningún momento, las herramientas pueden tener y Puede usarse, no heredarse.)
  • Ley de Dimit: La ley de Dimit también se denomina principio de conocimiento mínimo Un objeto debe tener el menor conocimiento posible sobre otros objetos. (La ley de Demeter simplemente significa cómo lograr un "acoplamiento bajo". El modelo de fachada y el modelo de mediador son la práctica de la ley de Demeter. Para el modelo de fachada, puedes dar un ejemplo simple, vas a una empresa para negociar negocios, No es necesario que entiendas cómo funciona la empresa internamente. Ni siquiera puedes saber nada sobre la empresa. Cuando vayas, solo necesitas encontrar la belleza en la recepción en la entrada de la empresa y decirles lo que vas a hacer. Ellos encontrarán a la persona adecuada para seguir. Usted contacta, la belleza en la recepción es la fachada del sistema de la empresa. No importa cuán complejo sea el sistema, puede proporcionar a los usuarios una fachada simple. ¿No es el Servlet o el Filtro como el controlador frontal en el desarrollo web Java solo una fachada? El navegador es el servidor El modo de funcionamiento es desconocido, pero a través del controlador frontal puede obtener el servicio correspondiente según su solicitud. El modo de mediador también se puede ilustrar con un ejemplo simple, como una computadora, CPU, memoria, disco duro, tarjeta gráfica, tarjeta de sonido Varios dispositivos deben cooperar entre sí para funcionar bien, pero si estos elementos están conectados directamente, el cableado de la computadora será extremadamente complicado. En este caso, la placa base aparece como un mediador y conecta cada dispositivo a No es necesario intercambiar datos directamente entre cada dispositivo, lo que reduce el acoplamiento y la complejidad del sistema, como se muestra en la figura siguiente. La regla de Dimit es usar palabras populares para no tratar con extraños, si es cierto Necesita encontrar un amigo suyo y dejar que se ocupe de los extraños por usted).

Preguntas de la entrevista de Complete Works of Java (9)
Preguntas de la entrevista de Complete Works of Java (9)

90. Describe brevemente los patrones de diseño que conoces.

Respuesta: El llamado patrón de diseño es un resumen de un conjunto de experiencias de diseño de código que se ha utilizado repetidamente (una solución probada a un problema en una situación). El uso de patrones de diseño es para reutilizar el código, facilitar la comprensión de otros y garantizar la confiabilidad del código. Los patrones de diseño permiten a las personas reutilizar diseños y arquitecturas exitosos de manera más simple y conveniente. Expresar tecnologías probadas en patrones de diseño también facilitará que los desarrolladores de nuevos sistemas comprendan sus ideas de diseño.
En "Patrones de diseño: elementos de software orientado a objetos reutilizables" de GoF, tres tipos (tipo creado [abstracción del proceso de creación de instancias de la clase] y tipo estructural [describen cómo combinar clases u objetos para formar un más Estructura grande], conductual [abstrayendo la división de responsabilidades y algoritmos entre diferentes objetos]), un total de 23 patrones de diseño, que incluyen: Abstract Factory (Abstract Factory), Builder (Builder), Factory Method ( Modo de método de fábrica), Prototipo (modo de modelo original), Singleton (modo de singleton); Fachada (modo de fachada), Adaptador (modo de adaptador), Puente (modo de puente), Compuesto (modo compuesto), Decorador (modo decorativo), Flyweight (Modo Flyweight), Proxy (modo de agente); Comando (modo de comando), Intérprete (modo de intérprete), Visitante (modo de visitante), Iterador (submodo iterativo), Mediador (modo de mediador), Memento (modo de memorándum) ), Observador (modo de observador), Estado (modo de estado), Estrategia (modo de estrategia), Método de plantilla (modo de método de plantilla), Cadena de responsabilidad (modo de cadena de responsabilidad).
Cuando se le pregunte sobre el conocimiento de los patrones de diseño en la entrevista, puede elegir las respuestas más utilizadas, como:

  • Patrón de fábrica: la clase de fábrica puede generar diferentes instancias de subclase según las condiciones. Estas subclases tienen una clase principal abstracta común e implementan los mismos métodos, pero estos métodos realizan diferentes operaciones (métodos polimórficos) para diferentes datos. Después de obtener la instancia de la subclase, el desarrollador puede llamar al método en la clase base sin tener que considerar qué instancia de la subclase se devuelve.
  • Modo proxy: proporcione un objeto proxy a un objeto, y el objeto proxy controla la referencia del objeto original. En el desarrollo real, los agentes se pueden dividir en agentes remotos, agentes virtuales, agentes de protección, agentes de caché, agentes de firewall, agentes de sincronización y agentes de referencia inteligentes de acuerdo con el propósito de uso.
  • Patrón de adaptador: transforme la interfaz de una clase en otra interfaz que el cliente espera, de modo que las clases que no se pueden usar juntas debido a una discrepancia de interfaz puedan trabajar juntas.
  • Patrón de método de plantilla: proporcione una clase abstracta, implemente parte de la lógica en forma de métodos o constructores concretos, y luego declare algunos métodos abstractos para forzar a las subclases a implementar la lógica restante. Diferentes subclases pueden implementar estos métodos abstractos (implementación polimórfica) de diferentes formas para lograr una lógica empresarial diferente.
    Además, también se puede hablar del modo fachada, modo puente, modo singleton, modo decoración (el modo decoración se usa en las herramientas de Colecciones y sistemas de E / S) mencionado anteriormente. De todos modos, el principio básico es elegir el más familiar La respuesta es la más utilizada, para no perderse

Supongo que te gusta

Origin blog.51cto.com/15061944/2593697
Recomendado
Clasificación