BUAA OO Unit2 Resumen

BUAA OO Unit2 Resumen

1. Estrategia de diseño

  Ya en mi primer año, escuché un poco sobre las operaciones de ascensores de OO, por lo que cuando esperaba el elevador, siempre pensaba en secreto: ¿Cómo está programado el elevador? En esta unidad, realmente experimenté el misterio de la programación de subprocesos y subprocesos múltiples.

  El elevador que utilizamos para estas tres operaciones es un tipo de elevador especial seleccionado para un elevador. Los pasajeros están fuera del elevador, salen de su propio piso de destino, como una solicitud para ingresar al sistema de elevadores. Necesitamos despachar ascensores según la solicitud de entrada.

Patrón de diseño

  En estas tres tareas, utilicé el modelo consumidor-productor.

  • Hilo de salida: como productor, después de leer la solicitud desde la consola, coloque la solicitud en la cola de solicitudes en el planificador.
  • Subproceso de elevador: como consumidor, obtenga la solicitud de la cola de solicitudes del despachador y ejecute la solicitud de acuerdo con su propia lógica de operación.
  • Programador: como paleta, gestiona todas las variables compartidas. En el modo singleton, los productores y consumidores llaman a la instancia del despachador para acceder a las variables compartidas, y el despachador usa synchronizedpalabras clave para garantizar la atomicidad del acceso a las variables compartidas.

Estrategia de elevador a cuestas

  En las tres operaciones, utilicé el algoritmo LOOK para la estrategia de elevador, que es simplemente:

  • El elevador no distingue entre solicitudes mayores y menores.
  • El elevador funcionará en la dirección actual hasta que necesite girar.
  • El elevador interactúa con la cola de solicitudes fuera del elevador en cada piso, y combina todas las solicitudes en la misma dirección cuando las condiciones lo permiten.

  Las condiciones para que el elevador gire son las siguientes:

  • El ascensor ha llegado al piso superior o a la planta baja.
  • El piso de destino sin pasajeros en el elevador está en la dirección actual
  • No hay una solicitud para el piso en la dirección actual, o hay una solicitud pero el elevador está completamente cargado

Solicitar estrategia de asignación

  Las operaciones sexta y séptima involucran la programación de múltiples elevadores, por lo que hay un problema con la estrategia de asignación de solicitudes.

  Sexta tarea

  En el sexto trabajo, no utilicé la estrategia de despachador, pero dejé que el ascensor "robara a las personas" por sí mismo. Cuando llegue la solicitud, notifique a todos los ascensores, el ascensor que llegue primero al piso de salida recibirá la solicitud y borrará la solicitud de la cola de solicitudes del despachador.

  La ventaja de dicha programación es garantizar que cada solicitud pueda ingresar al elevador lo antes posible, de modo que se pueda acortar el tiempo total de funcionamiento. Aunque hará que todos los ascensores se junten, el impacto en el rendimiento no es grande.

  Para el fenómeno de los ascensores atascados, hice una pequeña optimización, es decir, cuando el elevador está inicialmente inactivo, se detiene en diferentes pisos por defecto, lo que puede dispersar el elevador hasta cierto punto y, en algunos casos, puede optimizar el rendimiento del elevador. .

  Séptima tarea

  En el séptimo trabajo, debido a que involucra el problema de transferencia del elevador, entonces en el séptimo trabajo, adopté la estrategia de que el despachador asignó la solicitud al elevador.

  Teniendo en cuenta que el elevador A tiene la velocidad más rápida y solo el elevador A puede alcanzar los pisos 3 y 15 a 20; el elevador B tiene velocidad moderada, gran capacidad y el alcance más amplio de aplicación; aunque el elevador C tiene la velocidad más lenta, involucra un piso especial 3 Piso. Por lo tanto, la distribución de solicitud utiliza la siguiente estrategia:

  • Todas las solicitudes de pisos de destino en -3 a 1 y 15 a 20 pisos tienen prioridad para el elevador A
  • Las solicitudes de pisos impares a impares en los pisos intermedios (pisos 2 al 14) tienen prioridad para el elevador C
  • Todas las solicitudes restantes se asignan al elevador B

  Si bien dicha estrategia de asignación no es la estrategia de asignación óptima, puede garantizar que la solicitud se pueda distribuir uniformemente a cada elevador. .

  Además, debido a que algunos pisos solo pueden ser alcanzados por ciertos ascensores, se requiere dividir la solicitud:

  • Establecer pisos de tránsito: pisos 1 y 15
  • Las solicitudes para los pisos intermedios a -3 ~ -1 y 16-20 pisos deben dividirse
  • Las solicitudes para ir a los pisos pares en el tercer piso o al tercer piso en los pisos pares deben dividirse
  • Hay una cola de solicitud de caché en el planificador. La segunda fracción de solicitud se almacena temporalmente en la cola de caché. Después de esperar la ejecución de la primera solicitud, el elevador ajustará el método del planificador para eliminar la segunda solicitud de la cola de caché. Sáquelo y asígnelo al elevador de acuerdo con las reglas de asignación anteriores

Estrategia de diseño insuficiente

  Después de que termine la tarea, analice y reflexione sobre su estrategia de diseño y encuentre las siguientes deficiencias:

  • En el séptimo trabajo, debido a que implica asignar la solicitud al elevador para que funcione, el planificador necesita saber el estado de funcionamiento del elevador. El método que uso es llamar al método del elevador en el programador para obtener el estado de funcionamiento del elevador. Este es un método muy malo. Llamar al método de otro subproceso en un subproceso puede causar problemas de seguridad del subproceso. En la clase, el maestro introdujo el método del panel de estado. El hilo del elevador publicó activamente el estado en el panel de estado. El planificador lee el estado del elevador desde el panel de estado, que es mucho mejor que el método de llamar al elevador en el planificador.
  • Además, cuando me transfiero a un elevador, solo asigno la solicitud del segundo escalón al elevador siguiente después de que se complete la ejecución de la solicitud del primer escalón, de modo que después de que las personas se bajen del elevador del primer escalón, todavía tengan que esperar al segundo elevador Al llegar al piso de transferencia, esto perderá mucho tiempo, lo que resultará en un bajo rendimiento. El enfoque correcto debe estar en el proceso de solicitar la ejecución del primer paso. Si el ascensor siguiente está inactivo, debe llegar al piso de transferencia con anticipación y esperar.

2. Análisis de medición

2.1 El primer análisis de estructura de código de trabajo

  Diagrama UML

  Diagrama de tiempos UML

  Análisis de complejidad de código

  Se puede ver que la complejidad de vuelta promedio y la complejidad de vuelta total de despachadores y elevadores son relativamente altas.

  El método con mayor complejidad en el despachador es un método para que un elevador verifique si hay una nueva demanda en el piso y para obtener el piso donde se ubica la nueva demanda. Este método involucra muchas estructuras if_else, y hay muchas ramas y operaciones que en realidad son redundantes y se pueden hacer Algunas optimizaciones

  El método con mayor complejidad en el elevador es el método para juzgar si necesita girar y el método para decidir la siguiente acción (si necesita dormir y la acción que se tomará después del final del sueño). Los dos métodos están altamente acoplados y también involucran mucho Rama condicional. Desafortunadamente, por el momento aún no he podido encontrar un método efectivo para optimizar estas dos funciones.

2.2 Análisis de la estructura del segundo código de trabajo

  Diagrama UML

  Diagrama de tiempos UML

  Análisis de complejidad.

  En la segunda asignación, básicamente seguí el diseño de la primera asignación, por lo que no hubo cambios importantes en el conjunto y la complejidad del método fue básicamente similar a la primera asignación. Todavía hay varios métodos que involucran muchos juicios condicionales La complejidad es mayor.

2.3 El tercer análisis de la estructura del código de trabajo

  Diagrama UML

  Diagrama de tiempos UML

  Análisis de complejidad.

  Debido a que el tercer trabajo utiliza un método de solicitud de asignación diferente al de los dos trabajos anteriores, la estructura general del código es bastante diferente de los dos trabajos anteriores.

  Debido a que la cola de solicitud local del elevador se coloca en la clase de elevador, la clase de elevador de mi tercer trabajo es muy grande y complicada, lo que obviamente no es un buen diseño de estructura de código. Una mejor estructura de código debería ser separar la cola de solicitud local del subproceso del ascensor e incluso abstraer el algoritmo de programación del ascensor en un subprogramador.

  En el planificador global, debido a que involucra instrucciones divididas y solicitudes de asignación, las cuales involucran una gran cantidad de juicios de condición, la complejidad de los métodos relacionados es relativamente alta, y actualmente no existe una solución efectiva.

  Vale la pena mencionar que el código de mi fábrica de ascensores está relativamente desestructurado, principalmente porque esta operación solo implica la construcción de tres ascensores, por lo que solo escribí un modelo de fábrica simple. Obviamente, la estructura y la escalabilidad de un programa de diseño de este tipo son deficientes, lo que no es propicio para el desarrollo iterativo. Es un comportamiento personal perezoso y no es deseable en el desarrollo real del programa.

2.4 Análisis de principios sólidos

Principio de responsabilidad única de SRP

  En mi diseño, el subproceso de entrada solo es responsable de procesar la entrada de la consola y enviar las solicitudes, el subproceso del elevador solo es responsable de sus propias solicitudes de operación y ejecución, y el planificador general es responsable de recibir solicitudes, procesar solicitudes y distribuir solicitudes a los ascensores. . Pero el diseño puede ser más optimizado. Por ejemplo, el algoritmo de programación del ascensor se abstrae por separado. La clase de ascensor solo es responsable de abrir y cerrar puertas y subir y bajar personas, lo que también puede facilitar la optimización posterior.

Principio abierto y cerrado de OCP

  En las tres operaciones, el algoritmo de operación del elevador es básicamente el mismo que la primera operación. Solo de acuerdo con las instrucciones se han modificado algunas restricciones, por lo que la operación del elevador básicamente logra el principio OCP.

  El primer y segundo trabajo del planificador prácticamente no han cambiado, pero el tercer trabajo ha realizado una modificación importante. En particular, el tercer trabajo configuró una cola de solicitud local para cada elevador y fusionó la cola de solicitud local en la clase de elevador. En ese momento, este método fue adoptado solo para la conveniencia de algunas operaciones, pero este no fue un buen método de diseño, rompiendo la estructura de diseño original.

Principio de sustitución de LSP Leeb

  Ninguna de las tres tareas involucraba herencia.

Principio de separación de la interfaz ISP

  Solo los hilos existentes heredan la Runnableinterfaz.

DIP se basa en el principio de inversión

  En la séptima operación, la clase de elevador es una estructura abstracta, los tres elevadores dependen de la misma clase de elevador, que se ajusta al principio DIP.

3. PRUEBA Y ERRORES

3.1 Analice el error de su programa

  En la prueba fuerte y la prueba mutua de los tres trabajos, se encontró un error en la prueba fuerte del primer trabajo, porque después de que se despertó el subproceso del elevador, la condición para determinar si el subproceso debe finalizar no se agregó a la "cola de solicitudes y la cola de pasajeros en el elevador". Debería estar vacío ", por lo que hay un error de que se pierde el último hilo y el hilo del elevador termina prematuramente en un punto de prueba fuerte.

3.2 Encontrar errores en los programas de otras personas

  La estrategia adoptada en la prueba mutua sigue siendo la prueba de cobertura de la máquina de prueba automática y una pequeña cantidad de voladura de punto fijo de datos extremos.

  En esta tarea, los errores de todos son obviamente mucho menores, y después de la fuerte tormenta de la primera unidad, los programas de todos son mucho más defensivos. Los únicos pocos errores encontrados también son causados ​​por la seguridad del hilo, así que no entraré en detalles aquí.

4. Experiencia

  • Primera exposición a subprocesos múltiples. La asignación en esta unidad fue la primera vez que estuve expuesto a la programación multiproceso. Al final de la clase, todavía estaba confundido acerca del multiproceso. No entendía la sincronización de subprocesos o la esencia de los bloqueos. Cuando ocurre un error, no sé cómo depurar un programa multiproceso. Después de tres iteraciones de entrenamiento de tarea y aprendizaje sobre el mecanismo de semáforo en el curso de SO, gradualmente obtuve un poco de comprensión preliminar de subprocesamiento múltiple.
  • La seguridad del hilo es importante. La parte más atormentadora de esta unidad es el problema de seguridad del hilo. Por un lado, las condiciones de aparición de algunos errores de seguridad de subprocesos son muy metafísicas, y la máquina de evaluación local a veces no se puede medir; por otro lado, es más difícil reproducir el problema de seguridad de subprocesos localmente, lo que también causa ciertas dificultades para la depuración. Una vez que se produce el problema de punto muerto, la forma de resolver el punto muerto con gracia también es un gran problema y, a veces, incluso es necesario retrasar toda la arquitectura. Entonces, la mejor manera es pensar en la seguridad del hilo en todo momento cuando se piensa en el diseño y evitar puntos muertos en la fuente.
  • Hay una unidad arrepentida. De hecho, hay muchas cosas en las que vale la pena pensar en esta unidad. En el seminario una semana después del final de la tarea, así como en el área de discusión habitual, aprendí muchos algoritmos de peces gordos y varias estrategias de ajuste para encontrar la solución óptima, lo cual fue muy inspirador. Para estas tres tareas, debido a muchas razones subjetivas y objetivas y mi energía limitada, muchas ideas no se pudieron realizar. En cambio, tomé un enfoque más modesto y completé constantemente estas tres tareas. Si se basa únicamente en resultados, buscar la estabilidad puede ser un enfoque muy rentable. Pero para aprender, renunciar al riesgo significa renunciar a la oportunidad de mejorar uno mismo. Espero renunciar a este enfoque tímido y conservador en el futuro aprendizaje OO, y explorar valientemente.

Supongo que te gusta

Origin www.cnblogs.com/liujiahe0v0/p/liujiahe_oo_summary.html
Recomendado
Clasificación