Resumen de la operación de la Unidad 2 de la Universidad de Beihang (2.1 ~ 2.3)

  Después de una comprensión preliminar de los pensamientos de programación orientada a objetos en la primera unidad, Ben Kogan comenzó la segunda unidad de aprendizaje multihilo. La operación de esta unidad es construir un modelo calificado de "elevador de destino", diseñar el algoritmo de programación por sí mismo, realizar una programación razonable y satisfacer las necesidades de todos los pasajeros. Dado que las solicitudes y operaciones de elevadores son operaciones en tiempo real, se requiere un diseño de subprocesos múltiples.


Primera tarea

1. Etapa de construcción

  La demanda para esta operación es diseñar un único elevador que pueda ser transportado a cuestas. El piso del elevador es de 1 a 15 pisos. La estrategia de transporte a cuestas puede diseñarse por sí misma, y ​​la capacidad del elevador no está limitada. Después de comparar exhaustivamente una variedad de algoritmos de programación de elevadores, adopté la siguiente estrategia de programación: cuando no hay nadie en el elevador, se usa el algoritmo LOOK; cuando hay alguien en el elevador, la estrategia ALS superpuesta dada en la guía se usa para superponerse. En términos generales, el algoritmo es más fácil de implementar y el rendimiento también está garantizado.

  Para la construcción de la clase, construí principalmente dos clases de subprocesos: Inputter y Elevator , y construí la clase Controller Controller , que es responsable de la programación del personal. Inputter y Elevator usan el modelo clásico productor-consumidor, comparten objetos del Controlador y usan métodos de sincronización al acceder al Controlador . Además, debido a que el algoritmo LOOK se usa muchas veces, construí la clase de herramienta LOOK para el cálculo. Tema se detiene en el tema, que La unidad de entrada clara interfaz de entrada condición de parada, cuando La unidad de entrada le indica al controlador cuando parar. Para el subproceso del elevador, cuando no hay nadie en el elevador, la solicitud principal se obtiene del controlador. Hay tres casos:

1. Si la cola de solicitudes no está vacía, agregue directamente la primera solicitud al elevador

2. La cola de solicitud está vacía, pero el dispositivo de entrada no se detiene, luego espere

3. La cola de solicitud está vacía y el dispositivo de entrada se ha detenido, luego la solicitud obtenida devuelve nulo, lo que indica que el subproceso del elevador está detenido.

  El diagrama de clase se muestra a continuación:

 

Análisis de complejidad:

La mayoría de los métodos con mayor complejidad son analizados por algoritmos, los métodos restantes tienen menor complejidad y el grado de acoplamiento de los algoritmos clave es aún mayor.

2. Etapa de evaluación

Fase de prueba fuerte:

  Dado que el algoritmo de elevación del elevador no se diseñó científicamente al principio, muchas solicitudes que podrían ser superpuestas se negaron a superponerse, lo que resultó en que los puntos de datos individuales finales se juzgaron directamente incorrectamente debido al largo tiempo de programación, y la puntuación de rendimiento de los puntos de datos correctos también es muy baja.

Etapa de prueba mutua:

  Debido a que la estructura general del elevador es relativamente simple esta vez, no es fácil tener errores en la lógica de operación, por lo que no encontré ningún error durante la fase de prueba mutua. Utilicé el programa de generación automática de datos para enviar varios datos de prueba, pero no piratear a otros.

3. Reflexión y resumen.

  Esta tarea es el puntaje más bajo entre las tres tareas. Aunque la primera tarea es la más básica, pero no entendí el conocimiento de subprocesos múltiples en la primera semana, pasé mucho tiempo en la fase de escritura del programa para aprobar el examen y no optimicé demasiado. Esto conduce a un bajo rendimiento del programa. Por lo tanto, cuando aprende contenido nuevo en el futuro, debe comprenderlo desde el principio, de modo que pueda ahorrar mucho esfuerzo.

Segundo trabajo

1. Etapa de construcción

  En esta operación, sobre la base de la primera operación, se agregaron múltiples configuraciones de elevadores y se determinó el número de elevadores desde el principio. Al mismo tiempo, se aumentó la configuración del número de pasajeros en el elevador, y el piso operativo también se expandió al sótano (-1 ~ -3 pisos). En general, no hay muchos contenidos que necesiten expandirse para este trabajo, por lo que, en base al primer trabajo, cambié de un subproceso de elevador a varios subprocesos de elevador. Con el fin de reducir la cantidad de expansión y aumentar la capacidad de iteración, al principio separé estrictamente las solicitudes de la fila de ascensores de diferentes ascensores.Cuando se recibió una solicitud, la solicitud se agregó a la cola de solicitud de cierto elevador a través de un algoritmo, que no se pudo cambiar. Al diseñar el algoritmo de distribución, integré el principio del número promedio de ascensores y, al mismo tiempo, no fue fácil verse afectado por datos extremos. Se adoptó el principio de distribución aleatoria de números. Al mismo tiempo, se consideró la cola actual y el número de personas en el elevador, y se ajustó la frecuencia del intervalo de generación de números aleatorios (como el elevador A actual) Si el número de personas que esperan y el número de personas en el elevador son grandes, la frecuencia asignada al elevador A se reducirá en consecuencia. Este método de asignación se logra fácilmente ajustando el algoritmo de generación de números aleatorios.

  El algoritmo de programación de un solo elevador es básicamente el mismo que el de la primera operación, y la estrategia de lengüeta solo necesita agregar el número de personas. Otro punto a tener en cuenta en esta operación es que el número de ascensores debe determinarse en función de la entrada de la primera línea del hilo de entrada, y el hilo de entrada es un hilo separado. Por lo tanto, para reducir la interacción entre los hilos y garantizar la seguridad del hilo, el hilo del elevador El hilo del importador completa el establecimiento. El hilo principal solo implementa el establecimiento del controlador y el hilo del importador. La inicialización del controlador (esperando el establecimiento de la cola) también se completa en el hilo del importador.

   El diagrama de clase se muestra en la figura:

Análisis de complejidad:

  La complejidad es similar a la tarea anterior, principalmente porque la similitud entre las dos tareas es alta.

2. Etapa de evaluación

Fase de prueba fuerte:

  Dado que este trabajo utiliza un algoritmo de asignación relativamente bueno, el puntaje de rendimiento mejora considerablemente en comparación con el trabajo anterior. Sin embargo, debido a una falla importante en la construcción, se produjo un problema en el juicio de la capacidad del elevador, que me llevó a forzar la prueba a colgar directamente 3 puntos, el puntaje aún es bajo.

Etapa de prueba mutua:

  Como se mencionó anteriormente, debido a los errores en el código en sí, fui pirateado dos veces. Afortunadamente, fue un error homogéneo, que se fusionó y solucionó una vez. Además, envié múltiples datos a través del programa de generación automática de datos de prueba, pirateando a dos errores del compañero de cuarto.

3. Reflexión y resumen.

  El mayor problema de esta operación es que la prueba local no está en su lugar, la fuerza de los datos no es suficiente y depende demasiado de los resultados de la mitad de la prueba, por lo que no se han encontrado errores importantes. En futuras pruebas, haré todo lo posible para considerar los datos de prueba que pueden causar errores, construir muestras de prueba más específicas y aumentar la posibilidad de encontrar errores.

Tercera tarea

1. Etapa de construcción

  En esta operación, sobre la base de la operación anterior, se aumenta la configuración del tipo de elevador, los diferentes tipos de elevadores tienen diferente capacidad de pasajeros y diferentes pisos. Al mismo tiempo, la operación también agregó la configuración del cambio dinámico de la cantidad de ascensores. Inicialmente, hay tres ascensores y se pueden activar nuevos ascensores a la mitad. La interfaz de entrada también tiene ciertos cambios: las solicitudes se dividen en solicitudes de transporte y agregando solicitudes de ascensor.

  Clasificación del elevador, un problema muy común causado por diferentes pisos inmovilizables es que algunas solicitudes no pueden ser satisfechas por una operación de elevador (algunos pisos no pueden estacionarse) y deben transferirse. Por lo tanto, ya no es apropiado continuar usando la clase PersonRequest en la interfaz de salida como la clase de solicitud básica. En esta tarea, construí una clase MyRequest personalizada . Como no existe una situación en la que no se pueda alcanzar una transferencia, la clase MyRequest contiene dos objetos PersonRequest , que representan dos solicitudes antes y después de la transferencia (ambas son solicitudes atómicas y se puede acceder a la vez). Si no hay transferencia, este último se establece en nulo. El método clave de MyRequest , convertir, representa la transferencia. La solicitud después de la transferencia se asigna a la solicitud antes de la transferencia, y se establece en nulo, para que pueda satisfacer las necesidades de transferencia. Además, utilicé el modo de fábrica al generar Myrequest , calculé la ruta de transferencia después de ingresar una solicitud original del dispositivo de entrada y evité generar demasiados cálculos en el subproceso del elevador.

  La dificultad de manejar los problemas de seguridad del hilo en esta operación se ha mejorado mucho, principalmente porque además del dispositivo de entrada generará una solicitud, el elevador también generará una solicitud (es decir, el elevador es tanto un consumidor como un productor), la complejidad de la interacción del hilo La mejora es mayor. Además, la seguridad del hilo y la parada correcta también es una dificultad en este trabajo. Debido a que el elevador mismo generará solicitudes, si se adopta el diseño de la última operación, la parada del dispositivo de entrada y el vacío del elevador se usan como condiciones de parada del elevador, lo que puede provocar que algunos pasajeros no lleguen al destino. Cada subproceso de ascensor era completamente independiente en el último trabajo. La detención de un elevador no afecta a otros ascensores, y los subprocesos de ascensor en este trabajo tienen interacción. Por lo tanto, para esta operación, utilicé "paradas de entrada y todos los ascensores están inactivos" como condiciones para que los ascensores se detengan al mismo tiempo.

  El elevador inactivo significa que el elevador está vacío y no hay nuevas solicitudes. Debido a que el elevador está inactivo y el dispositivo de entrada se detiene (el dispositivo de entrada se detiene en un estado permanente, no se encenderá nuevamente después de detenerse, y el elevador cambia dinámicamente), por lo que utilicé el "modo de observador" y el controlador actúa como un oyente. Rol, el elevador actualiza su propio estado cada vez que se procesa una solicitud e informa al oyente, quien luego actualiza el estado del elevador. Dado que un cierto elevador solo puede obtener el estado de otros elevadores del controlador, el método para adquirir el estado y actualizar el estado debe ser un método sincrónico.

  El diagrama de clase es como se muestra (debido a que hay muchos métodos para este trabajo, los métodos internos no se muestran en el diagrama de clase):

Análisis de complejidad (demasiados métodos, solo se publican algunos métodos con mayor complejidad):

2. Etapa de evaluación

Fase de prueba fuerte:

  En esta tarea, aprendí las lecciones de las dos tareas anteriores y realicé muchas evaluaciones. No hubo errores en la prueba sólida, pero el puntaje general de rendimiento fue bajo.

Etapa de prueba mutua:

  Sobreviví a esta fase de prueba mutua. Por supuesto, no encontré los errores de otras personas ni siquiera descargué el código de otras personas .

3. Reflexión y resumen.

  El principal problema de esta operación es que el rendimiento de la prueba fuerte es demasiado bajo y el rendimiento de muchos puntos de prueba es 0 . La comparación entre las dos asignaciones anteriores se debe principalmente a que no pasé suficiente tiempo en el diseño del algoritmo de transferencia , o que el algoritmo relacionado no lo hace . Utilizo un "algoritmo de transferencia de números aleatorios" similar al algoritmo de programación, pero este trabajo es obviamente inapropiado. Primero, debido a que cada elevador funciona a una velocidad diferente, intente utilizar el elevador que funciona más rápido. Segundo, porque se genera el número aleatorio Algunos de los pisos de transferencia pueden funcionar en vano (por ejemplo, de 3 a 9, lo que resulta en un número aleatorio de 15, lo que resulta en una ruta de transferencia de 3 → 15 → 9, obviamente irrazonable), por supuesto, puede haber otras razones. El diseño de la asignación de este trabajo en realidad está relacionado con el conocimiento de la estructura de datos, por lo que consolidaré el conocimiento de la estructura de datos en el futuro, aprenderé más sobre el conocimiento del algoritmo y mejoraré en los detalles.

Pensamiento maleable

  Elevator es una herramienta muy utilizada en la vida y puede ampliarse debido a diversas necesidades, lo que se puede realizar cuando se extiende el código. El análisis del ascensor diseñado por esta unidad puede revelar cierta irracionalidad. Por ejemplo, los ascensores solo tienen como objetivo cumplir con todas las solicitudes de pasajeros y no consideran el orden de satisfacer las necesidades. En realidad, si un elevador a menudo permite que un pasajero que llegue por primera vez espere demasiado, entonces el usuario no lo aprobará. Por lo tanto, puede ser posible proceder del desempeño cuando se expande, y tomar el tiempo de espera del pasajero como parte del puntaje de desempeño, y el tiempo de espera de cada pasajero tiene una relación no lineal con la reducción del desempeño (la paciencia del pasajero a menudo aumenta con el tiempo de espera Fuerte caída). Al mismo tiempo, al establecer prioridades para diferentes pasajeros, los pasajeros con diferentes prioridades que esperan al mismo tiempo tienen diferentes impactos en el rendimiento.

  El elevador de esta unidad adopta una limitación simple del número de pasajeros, y la realidad es que la capacidad de pasajeros del elevador está relacionada con el peso del pasajero, y el peso del pasajero se da en el momento de la entrada. Además, en realidad, los pasajeros no pueden saber su peso antes de ingresar al elevador, por lo tanto, se debe realizar una programación más razonable para reducir la pérdida de tiempo causada por problemas de peso al abrir y cerrar puertas y afectar el rendimiento.

 


 Resumen de la unidad

  El diseño de subprocesos múltiples es un problema que a menudo se encuentra en la programación. En el estudio de esta unidad, aprendí la forma en que JAVA realiza el subprocesamiento múltiple y el principio de la programación de subprocesos, y aprendí el clásico "modelo productor-consumidor". El "modelo de observador" y otros marcos han mejorado aún más mis capacidades de programación. La seguridad de los subprocesos es un tema importante que debe abordarse en el diseño de subprocesos múltiples. Todavía tengo una falta de procesamiento en esta área. Continuaré consolidando el conocimiento relevante en la medida en que sea competente en el diseño de subprocesos múltiples.

Supongo que te gusta

Origin www.cnblogs.com/zxc3wyx/p/12694589.html
Recomendado
Clasificación