Existen 16 buenos hábitos para escribir código, que pueden reducir los errores no comerciales en un 80%

Este artículo es mi número público de micro-canales, " la tecnología de back-end de Java para ver el" Autor: recoger al niño caracol. Compártelo si crees que es bastante bueno y respeta la originalidad.

Tabla de contenido

Prefacio

Todo buen hábito es una riqueza. Este artículo ha recopilado 16 buenos hábitos para escribir código, cada uno de los cuales es muy clásico. ¡Al desarrollar estos hábitos, puede evitar la mayoría de los errores no comerciales! Espero que ayude a todos, gracias por leer, vamos ~

1. Después de modificar el código, recuerde probarse usted mismo

"Después de cambiar el código, la autocomprobación" es una cualidad básica que todo programador debe tener. Especialmente no tengo esta casualidad "Psicología: acabo de cambiar una variable o sólo cambié una línea de código de configuración, no es necesario realizar una autocomprobación". Después de cambiar el código, intente preguntarse a sí mismo para probarlo, puede evitar muchos errores innecesarios.

2. Intente comprobar los parámetros de entrada del método

La verificación de entrada también es una cualidad básica que todo programador debe tener. Su método maneja "los parámetros deben ser verificados primero". Por ejemplo, si el parámetro de entrada puede estar vacío y si la longitud del parámetro de entrada cumple con la longitud esperada. Trate de acostumbrarse a esto. Muchos "errores de bajo nivel" son causados ​​por "no verificar los parámetros".
Si el campo de su base de datos se establece en varchar (16) y la otra parte envía una cadena de 32 bits, no verifica los parámetros y "insertar la base de datos directamente es anormal".

3. Al modificar la interfaz anterior, tenga en cuenta la compatibilidad de la interfaz.

Muchos errores se deben a la modificación de la interfaz externa anterior, pero "no son compatibles". El problema clave es mayormente serio, lo que puede conducir directamente al fallo de la versión del sistema. Los programadores novatos pueden cometer este error fácilmente ~
Por lo tanto, si su requisito es modificar la interfaz original, especialmente si esta interfaz es para proporcionar servicios externos, debe considerar la compatibilidad de la interfaz. Por ejemplo, por ejemplo, la interfaz dubbo originalmente solo recibía los parámetros A y B, pero ahora agrega un parámetro C, puede considerar hacer esto.

//老接口
void oldService(A,B);{
    
    
  //兼容新接口,传个null代替C
  newService(A,B,null);
}
//新接口,暂时不能删掉老接口,需要做兼容。
void newService(A,B,C);

4. Para una lógica de código compleja, agregue comentarios claros

Al escribir código, no es necesario escribir demasiados comentarios, el mejor comentario es un buen nombre de variable de método. Sin embargo, si se trata de "código con lógica empresarial compleja", es realmente necesario escribir "comentarios claros". Las notas claras son más propicias para el mantenimiento posterior.

5. Después de usar el flujo de recursos de E / S, debe cerrarse.

Todo el mundo debería haber tenido esta experiencia Si el escritorio del sistema de Windows "abre demasiados archivos" o el software del sistema, sentirá que la computadora está atascada. Por supuesto, nuestro servidor Linux también es el mismo. Si el flujo de recursos de E / S no se cierra durante el funcionamiento normal de los archivos o las conexiones de bases de datos, entonces este recurso de E / S estará ocupado por él, de modo que otros no puedan usarlo, lo que provoca que el "recurso residuos".

Entonces, después de usar el flujo IO, puede usar finalmente para cerrarlo.

FileInputStream fdIn = null;
try {
    
    
    fdIn = new FileInputStream(new File("/jay.txt"));
} catch (FileNotFoundException e) {
    
    
    log.error(e);
} catch (IOException e) {
    
    
    log.error(e);
}finally {
    
    
    try {
    
    
        if (fdIn != null) {
    
    
            fdIn.close();
        }
    } catch (IOException e) {
    
    
        log.error(e);
    }
}
JDK 7 之后还有更帅的关闭流写法,「try-with-resource」。
/*
 * 关注公众号,捡田螺的小男孩
 */
try (FileInputStream inputStream = new FileInputStream(new File("jay.txt")) {
    
    
    // use resources   
} catch (FileNotFoundException e) {
    
    
    log.error(e);
} catch (IOException e) {
    
    
    log.error(e);
}

6. El código toma medidas para evitar errores en tiempo de ejecución (como desbordamiento del límite de la matriz, división por cero, etc.)

En el desarrollo diario, debemos tomar medidas para evitar errores en tiempo de ejecución como "desbordamiento de límites de matriz, divisible por cero, puntero nulo" y otros errores en tiempo de ejecución.
Los códigos similares son más comunes:

String name = list.get(1).getName(); //list可能越界,因为不一定有2个元素哈
所以,应该「采取措施,预防一下数组边界溢出」,正例:
if(CollectionsUtil.isNotEmpty(list)&& list.size()>1){
    
    
  String name = list.get(1).getName(); 
}

7. Trate de no realizar llamadas remotas u operaciones de bases de datos en el bucle y dé prioridad a los lotes.

Las operaciones remotas o las operaciones de la base de datos son "más recursos de red y de E / S", así que trate de no llamar de forma remota en un bucle ni operar la base de datos en un bucle. Puede "volver a comprobarlo en lotes a la vez e intentar no hacerlo varias veces . " (Pero no verifique demasiados datos a la vez, sino 500 salsas en lotes)

正例:
remoteBatchQuery(param);
反例:
for(int i=0;i<n;i++){
    
    
  remoteSingleQuery(param)
}

8. Después de escribir el código, piense en cómo sucederá la ejecución de subprocesos múltiples y preste atención a los problemas de concurrencia.

Algunos escenarios comerciales que vemos a menudo son verificar si hay un registro primero y luego realizar la operación correspondiente (como la modificación). Sin embargo, la combinación de (consulta + modificación) no es una operación atómica. Si tienes varios hilos en tu cerebro, encontrarás que hay un problema. El
contraejemplo es el siguiente:

if(isAvailable(ticketId){
    
     
    1、给现金增加操作 
    2deleteTicketById(ticketId) 
}else{
    
     
    return "没有可用现金券";
}

Para entenderlo más fácilmente, mire este diagrama de flujo:
Inserte la descripción de la imagen aquí

1. Subproceso A más efectivo
2. Subproceso B más efectivo
3. El subproceso A borra la bandera del ticket
4. El subproceso B borra la bandera del ticket
Obviamente hay un "problema de concurrencia", el ejemplo positivo debería "usar la atomicidad de la operación de eliminación de la base de datos ", como sigue:

if(deleteAvailableTicketById(ticketId) == 1){
    
     
    1、给现金增加操作 
}else{
    
     
    return “没有可用现金券” 
}

Por lo tanto, este hábito también es necesario: "Después de escribir el código, si desea ejecutarlo en varios subprocesos, habrá problemas de coherencia de concurrencia".

9. Obtenga las propiedades del objeto, primero determine si el objeto está vacío

Este punto originalmente pertenecía a "tomar medidas para evitar excepciones en tiempo de ejecución", pero aún lo tomé como un punto clave para escribir, porque generalmente la excepción de puntero vacío es demasiado común y no se nota un apretón de manos, lo que causa el puntero nulo para informar a producción. El medio ambiente se ha ido.
Por lo tanto, cuando desee obtener los atributos de un objeto, trate de no creer que "lo teórico no es vacío", fácilmente desarrollamos el hábito de juzgar si está vacío o no, y luego obtenemos los atributos del objeto. Ejemplo positivo:


if(object!=null){
    
    
   String name = object.getName();
}

10. La prioridad asincrónica de subprocesos múltiples considera el grupo de subprocesos apropiado en lugar del nuevo subproceso y considera si el grupo de subprocesos está aislado

¿Por qué utilizar primero el grupo de subprocesos? Hay varias ventajas de usar el grupo de subprocesos:
nos ayuda a administrar los subprocesos y evitar el aumento del consumo de recursos al crear y destruir subprocesos.
Mejora la velocidad de respuesta.
Reutilizar.
Al mismo tiempo, trate de no compartir un grupo de subprocesos para todas las empresas, debe considerar el "aislamiento del grupo de subprocesos". Es un negocio clave diferente, asigna diferentes grupos de subprocesos, y luego los parámetros del grupo de subprocesos deben considerarse de manera apropiada.

11. Después de escribir manualmente el SQL del código empresarial, primero llévelo a la base de datos y ejecútelo, y también explique para ver el plan de ejecución.

Después de escribir manualmente el SQL del código comercial, puede llevarlo a la base de datos y ejecutarlo para ver si hay errores de sintaxis. La mala costumbre de algunos socios pequeños es empaquetar el código y probar el servidor después de escribir, de hecho, poner SQL en la base de datos para su ejecución puede evitar muchos errores.
Al mismo tiempo, también use "explicar para ver su plan de ejecución de SQL", especialmente si no puede ir al índice.

explain select * from user where userid =10086 or age =18;

12. Al llamar a una interfaz de terceros, debe considerar el manejo de excepciones, la seguridad y el reintento del tiempo de espera.

Si llama a un servicio de terceros o servicio remoto distribuido, debe considerar el
manejo de excepciones (por ejemplo, si ajusta la interfaz de otra persona, si hay una excepción, cómo tratarla, reintentar o como una falla)
tiempo de espera ( No se puede predecir cuánto tiempo tardará la interfaz del otro en Devolver, generalmente establece un tiempo de desconexión de tiempo de espera para proteger su interfaz)
Número de reintentos (su interfaz falló, debe volver a intentarlo, debe pensar en este problema desde una perspectiva comercial) Un
ejemplo simple, realiza una solicitud http para los servicios de otras personas, debe considerar configurar el tiempo de conexión y los tiempos de reintento.

Si se trata de un servicio de terceros importante, como la transferencia de dinero, también debe considerar la "verificación de firma" y el "cifrado".

13. La interfaz debe considerar la idempotencia

Las interfaces deben considerarse idempotentes, especialmente las interfaces importantes como agarrar sobres rojos y transferir fondos. El escenario empresarial más intuitivo es "el usuario hace clic dos veces seguidas". ¿Su interfaz se mantiene?
Idempotente (idempotente, idempotencia) es un concepto matemático y de ciencias de la computación que se encuentra comúnmente en el álgebra abstracta.
En programación, la característica de una operación idempotente es que el efecto de cualquier número de ejecuciones es el mismo que el efecto de una ejecución. Las funciones idempotentes, o métodos idempotentes, son funciones que se pueden ejecutar repetidamente con los mismos parámetros y obtener los mismos resultados.
En general, existen varios tipos de "soluciones técnicas idempotentes":
operaciones de consulta, mecanismo de token de
índice único
, para evitar el envío repetido de
operaciones de eliminación de la base de datos,
bloqueos optimistas,
bloqueos pesimistas,
Redis, bloqueos distribuidos de zookeeper (anteriormente se utilizaban bloqueos distribuidos de Redis para tomar rojo sobres)
idempotencia de la máquina de estado

14. En el caso de subprocesos múltiples, considere las cuestiones de seguridad lineal

En el caso de "alta concurrencia", HashMap puede tener un bucle infinito. Debido a que no es linealmente seguro, puede considerar usar ConcurrentHashMap. Por lo tanto, intente desarrollar un hábito en la medida de lo posible. No
cree un nuevo HashMap (); Hashmap, Arraylist, LinkedList, TreeMap, etc. son todos linealmente inseguros;
Vector, Hashtable, ConcurrentHashMap, etc. son todos linealmente seguro

15. Considere el problema del retardo maestro-esclavo

Primero inserte, luego vaya a la consulta, este tipo de código lógico es más común, este "puede" ser problemático. Generalmente, la base de datos tiene una base de datos maestra y una esclava. Escribir es escribir en la biblioteca principal y leer generalmente es leer de la biblioteca. Si hay un retraso maestro-esclavo, es muy probable que su inserción sea exitosa, pero no puede encontrarlo.

Si se trata de un negocio importante, debe considerar si debe leer obligatoriamente la biblioteca principal o modificar el plan de diseño.
Sin embargo, algunos escenarios comerciales pueden aceptar un ligero retraso entre el maestro y el esclavo, pero este hábito sigue siendo necesario.
Después de escribir el código para operar la base de datos, piense si existe un problema de retraso maestro-esclavo.

16. Al utilizar la caché, tenga en cuenta la coherencia entre la caché y la base de datos, así como (penetración de caché, avalancha de caché y desglose de caché)

En términos sencillos, utilizamos el almacenamiento en caché para "una verificación rápida y una interfaz que requiere menos tiempo". Sin embargo, cuando se utiliza el almacenamiento en caché, es necesario "prestar atención a la coherencia de la caché y la base de datos". Al mismo tiempo, también es necesario evitar los tres problemas principales de penetración de caché, avalancha de caché y avería de caché.
Avalancha de caché: se refiere a la gran cantidad de datos en la caché hasta el momento de caducidad, y la gran cantidad de datos de consulta provoca una presión excesiva en la base de datos o incluso tiempo de inactividad.
Penetración de caché: se refiere a la consulta de ciertos datos inexistentes. Cuando se pierde el caché, es necesario consultarlo desde la base de datos. Si no se encuentran los datos, no se escribirán en el caché. Esto provocará que no se datos existentes para ir a la base de datos cada vez que se realiza una consulta, y luego presionar la base de datos.
Desglose de caché: se refiere a cuando la tecla de acceso rápido expira en un momento determinado, y una gran cantidad de solicitudes simultáneas para esta clave llegan en este momento, y una gran cantidad de solicitudes llegan a la base de datos.

Supongo que te gusta

Origin blog.csdn.net/qq_41936224/article/details/111469753
Recomendado
Clasificación