Saltar al contenido

Software de sistema

A-Level Ciencias de la Computación · Tema 16

Entrenar
Lección de video para este tema Abrir la página de video
14:07

Recursos, compiladores y RPN

Abre un navegador, un reproductor de música y un juego. Tienes un procesador — quizás varios núcleos — y todos parecen ejecutarse al mismo tiempo. Y juntos quieren más…

Narración en inglés · Subtítulos en inglés + 中文 quemados en pantalla

16.1

Cómo el SO maximiza el uso de recursos

Syllabus
Los candidatos deben ser capaces de: Notas y orientación
Demostrar comprensión de cómo un SO puede maximizar el uso de los recursos
Describir las formas en que la interfaz de usuario oculta las complejidades del hardware al usuario
Demostrar comprensión de la gestión de procesos El concepto de multitarea y un proceso
Los estados del proceso: ejecución, listo y bloqueado
La necesidad de planificación y la función y beneficios de diferentes rutinas de planificación (incluyendo round robin, shortest job first, first come first served, shortest remaining time)
Cómo el kernel del SO actúa como manejador de interrupciones y cómo el manejo de interrupciones se utiliza para gestionar la planificación a bajo nivel
Demostrar comprensión de la memoria virtual, el paginación y la segmentación para la gestión de memoria Los conceptos de paginación, memoria virtual y segmentación
La diferencia entre paginación y segmentación
Cómo pueden reemplazarse las páginas
Cómo puede ocurrir el thrashing (agotamiento) del disco

Fuente: Plan de estudios Cambridge International

Un ordenador dispone de muchos recursos (tiempo de CPU, memoria, disco, E/S) y varios programas compiten por ellos. El SO los comparte de forma justa y eficiente para que cada uno se utilice adecuadamente y el sistema permanezca reactivo:

El SO comparte tiempo de CPU, memoria, disco y entrada/salida entre programas
El SO comparte la CPU, la memoria, el disco y las E/S entre los programas
  • multitarea — cambiar rápidamente la CPU entre procesos para que varios parezcan ejecutarse a la vez.
  • gestión de memoria — asignar a cada proceso la memoria que necesita; utilizar el paging 分页 del disco cuando se agota la RAM.
  • spooling 假脱机 y buffering: las tareas de impresión se encolan en el disco para que la CPU nunca espere a la impresora.
  • caching: mantener datos recientes del disco en una cache 高速缓存 / RAM.
A CPU (central processing unit) chip
El procesador es un recurso clave que el SO comparte entre tareas competidoras
Memory modules (RAM)
El SO también gestiona la memoria (RAM), decidiendo qué mantener en ella y qué enviar al disco mediante paging
Vocabulario Entrenar
Inglés Chino Pinyin
multi-tasking/ˈmʌlti ˈtæskɪŋ/ 多任务 duō rèn wù
paging/ˈpeɪdʒɪŋ/ 分页 fēn yè
spooling/ˈspuːlɪŋ/ 假脱机 jiǎ tuō jī
cache/kæʃ/ 高速缓存 gāo sù huǎn cún
process/ˈprəʊses/ 进程 jìn chéng
scheduler/ˈʃedjʊlə/ 调度器 diào dù qì
16.1

La interfaz de usuario

La interfaz de usuario oculta el hardware detrás de abstracciones amigables: el usuario ve ventanas, menús y carpetas, no direcciones ni sectores. Un solo clic en un icono hace que el SO localice el programa en el disco, le asigne memoria, lo cargue y lo inicie. Una CLI (línea de comandos) es potente y scriptable para expertos; una GUI (gráfica) es más fácil de aprender. La mayoría de sistemas ofrecen ambos.

"Describa dos formas en que se ocultan al usuario las complejidades del hardware." (1) El usuario trabaja con archivos y carpetas por nombre, y el SO los traduce en pistas, sectores y bloques del disco; (2) el usuario ejecuta un programa con un clic o un comando, y el SO lo carga, le asigna memoria y lo programa sin que el usuario conozca ninguna dirección; (3) los controladores de dispositivo permiten al usuario imprimir o guardar sin saber cómo se controla la impresora o el disco; (4) una interfaz gráfica sustituye los comandos a nivel de máquina por iconos, ventanas y menús. El beneficio para un estudiante, con un ejemplo: el SO hace que el hardware sea utilizable sin conocimientos técnicos, por ejemplo, guardando un documento en una unidad USB arrastrando su icono.

"Muestre cómo un SO maximiza el uso de recursos." Programa el procesador para que nunca esté inactivo mientras haya un proceso listo; gestiona la memoria, asignándola a los procesos, recuperándola y ampliándola con memoria virtual; gestiona la entrada y salida, utilizando buffers y spooling para que dispositivos rápidos y lentos superpongan sus trabajos; y gestiona el almacenamiento, llevando un registro del espacio libre y los archivos. Cada punto nombra un recurso y lo que hace el SO con él.

16.1

Gestión de procesos

Un proceso 进程 es un programa en ejecución: su código, estado actual, memoria y archivos abiertos.

Programación

El programador 调度器 elige qué proceso listo se ejecutará a continuación y durante cuánto tiempo:

  • round robin 轮转 — cada proceso recibe un time slice 时间片 fijo y luego pasa al final de la cola.
  • primero en llegar, primero en ser atendido; trabajo más corto primero; tiempo restante más corto (ejecutar el trabajo con menos trabajo pendiente); prioridad; colas de retroalimentación multinivel.

El compromiso es la reactividad frente al rendimiento frente a la equidad.

"Describa lo que significa multitarea y cómo beneficia a la gestión de procesos." Varios procesos se mantienen en memoria al mismo tiempo y el procesador cambia entre ellos tan rápido que parecen ejecutarse simultáneamente, recibiendo cada uno turnos de tiempo de procesador a su vez. El beneficio: el procesador nunca queda inactivo mientras un proceso espera entrada o salida, por lo que el rendimiento es mayor y el usuario puede trabajar con varios programas a la vez. "Explique la necesidad de programar." Hay más procesos que procesadores, por lo que se debe decidir cuál proceso se ejecutará a continuación y por cuánto tiempo; la programación asegura que todos los procesos avanzen, que el procesador esté plenamente utilizado, que los tiempos de respuesta sean aceptables y que se puedan respetar las prioridades.

Dos líneas de tiempo de los mismos tres trabajos: primero en llegar, primero en servir ejecuta el trabajo largo primero y los trabajos cortos esperan detrás de él, mientras que primero en llegar el trabajo más corto ejecuta los trabajos cortos primero y reduce el tiempo de espera promedio de 6.7 a 2.7 unidades
Mismo trabajo en orden diferente: shortest-job-first elimina primero los trabajos cortos, por lo que la mayoría espera menos, con el riesgo de que un trabajo largo espere indefinidamente

Las rutinas de programación, tal como las pide el examen.

Rutina Función Beneficio Inconveniente
primero en llegar, primero en ser atendido (FCFS) los procesos se ejecutan en el orden en que llegan a la cola de listos, hasta completarse simple; cada proceso se atiende a su turno, ninguno es privado de servicio un proceso largo retrasa a todos los cortos que están detrás; mala respuesta
trabajo más corto primero (SJF) el proceso listo con el tiempo de ejecución estimado más corto se ejecuta a continuación, hasta completarse minimiza el tiempo de espera promedio; muchos trabajos cortos terminan rápidamente los tiempos de ejecución deben conocerse de antemano; un trabajo largo podría no ejecutarse nunca (privación de servicio)
tiempo restante más corto (SRT) versión preemptive 抢占式 de SJF: si llega un nuevo proceso con menos tiempo restante que el que se está ejecutando, toma el control los procesos cortos se atienden aún más rápido; buen rendimiento más cambios de contexto; un trabajo largo puede ser interrumpido repetidamente y sufrir privación de servicio
round robin (RR) cada proceso listo recibe un time slice fijo a su vez; cuando expira, el proceso pasa al final de la cola justo; cada proceso responde dentro de un tiempo acotado, bueno para uso interactivo sobrecarga por cambio de contexto; un time slice muy corto desperdicia tiempo, uno largo retrasa a otros
prioridad el proceso listo con mayor prioridad se ejecuta primero el trabajo importante o crítico en el tiempo se realiza primero los procesos de baja prioridad pueden sufrir privación de servicio a menos que las prioridades envejecan

Ejemplo resuelto. Tres procesos llegan juntos con tiempos de CPU de 8, 4 y 2 ms. Compare el tiempo de espera promedio bajo FCFS (en orden de llegada A, B, C) y bajo shortest job first.

FCFS: A espera 0, B espera 8, C espera 12; promedio $(0 + 8 + 12)/3 = 6.7\ \text{ms}$. SJF ejecuta C, B, A: C espera 0, B espera 2, A espera 6; promedio $2.7\ \text{ms}$. El trabajo total es el mismo, 14 ms en ambos casos; el orden decide quién espera. Round robin con un time slice de 2 ms daría a A, B y C un turno en los primeros 6 ms, por lo que C termina en 6 ms, B en 12 ms y A en 14 ms: el más reactivo, no necesariamente el más rápido en promedio.

Una línea de tiempo de Gantt que muestra P1 luego P2, P3, P4 ejecutándose uno tras otro desde el tiempo 0 hasta 39, con una clave que proporciona el tiempo de ráfaga de CPU de cada proceso
Programación primero en llegar, primero en ser atendido de cuatro procesos
Programación por turnos rotativos mostrada como una línea de tiempo: P1, P2, P3 cada uno recibe una porción fija de tiempo por turno, luego el ciclo se repite, compartiendo la CPU entre ellos
Round-robin: cada proceso recibe un time slice fijo a su vez, luego se ejecuta el siguiente (a diferencia de primero en llegar, primero en ser atendido)

Estados de proceso

Un proceso es nuevo, listo (esperando la CPU), en ejecución, bloqueado 阻塞 (esperando E/S o un bloqueo) o terminado. Cuando termina su time slice pasa de executing → ready; cuando solicita E/S pasa de executing → blocked; cuando finaliza la E/S pasa de blocked → ready.

Un diagrama de estados: nuevo a listo (admisión), listo a en ejecución (despacho por el planificador), en ejecución a listo (interrupción o expiración de tiempo), en ejecución a bloqueado (solicitud de E/S), bloqueado de vuelta a listo (E/S completada), en ejecución a terminado (salida)
Un proceso se mueve entre los estados new, ready, running, blocked y terminated

Los tres estados y las razones por las que un proceso cambia de estado. En ejecución: el proceso tiene el procesador. Listo para ejecutar: podría ejecutarse pero está esperando por el procesador. Bloqueado: no puede ejecutarse hasta que ocurra algo más. Razones para cada transición, lo cual el examen pide una a la vez: de ejecución a listo cuando termina su intervalo de tiempo, o cuando un proceso de mayor prioridad se vuelve listo y lo preempe (una interrupción); de ejecución a bloqueado cuando solicita entrada/salida o espera por un recurso u otro proceso; de bloqueado a listo cuando finaliza la E/S en la que estaba esperando (señalada por una interrupción); de listo a ejecución cuando el planificador lo despacha. Un proceso bloqueado nunca pasa directamente a ejecución: primero debe convertirse en listo.

Bloque de control de proceso y cambio de contexto

Para cada proceso, el SO mantiene un bloque de control de proceso 进程控制块 (PCB) — el contador de programa guardado, registros, estado e información de memoria.

Un cambio de contexto guarda el estado del proceso A (su PCB) y carga el del proceso B
Un cambio de contexto guarda el estado de un proceso y carga el de otro
  • un cambio de contexto 上下文切换 suspende un proceso e inicia otro: guarda el estado en un PCB y lo restaura desde otro. Este pequeño costo se paga en cada cambio.
  • el núcleo 内核 (el núcleo del SO) actúa como manejador de interrupciones 中断处理程序. Cuando un dispositivo o el temporizador generan una interrupción, el manejo de interrupciones 中断处理 salva el proceso en ejecución y ejecuta la rutina adecuada — esto es lo que impulsa la planificación de bajo nivel.

"Describa cómo actúa el núcleo como manejador de interrupciones" (dos puntos). Cuando se genera una interrupción, el núcleo guarda el estado del proceso en ejecución (sus registros y contador de programa, en su bloque de control de proceso), identifica la fuente y la prioridad de la interrupción, ejecuta la rutina de servicio de interrupción correspondiente y luego restaura el proceso interrumpido (o uno de mayor prioridad) para que la ejecución continúe. Así es como el temporizador termina un intervalo de tiempo y cómo una operación de E/S completada desbloquea un proceso.

Comunicación entre procesos

Los procesos están aislados, por lo que el SO proporciona comunicación entre procesos 进程间通信: tuberías 管道 (la salida de un programa alimenta la entrada de otro), memoria compartida 共享内存 (una región que varios procesos pueden usar) y paso de mensajes.

Explorar

La vida de un proceso

Toca alrededor del bucle que recorre un proceso. Solo se ejecuta cuando el planificador lo selecciona; necesitar E/S lo envía a bloqueado, y terminar su tiempo de CPU lo devuelve a listo — rode y rode hasta que termine.

Vocabulario Entrenar
Inglés Chino Pinyin
round robin/raʊnd ˈrɒbɪn/ 轮转 lún zhuàn
time slice/taɪm slaɪs/ 时间片 shí jiān piàn
pre-emptive/priː ˈemptɪv/ 抢占式 qiǎng zhàn shì
blocked/blɒkt/ 阻塞 zǔ sè
process control block/ˈprəʊses kənˈtrəʊl blɒk/ 进程控制块 jìn chéng kòng zhì kuài
context switch/ˈkɒntekst swɪtʃ/ 上下文切换 shàng xià wén qiè huàn
16.1

Memoria virtual, segmentación y paginación

Cada proceso recibe su propio espacio de direcciones virtuales 虚拟地址 espacio — un rango limpio y contiguo de direcciones que el SO mapea a la memoria física. Esto otorga a cada proceso un espacio sencillo, protege los procesos entre sí y permite que la memoria total exceda la RAM física.

En la paginación, el espacio virtual se divide en páginas 页 de tamaño fijo y la memoria física en marcos 页框 del mismo tamaño. Una tabla de páginas mapea cada página a un marco. Si una página accedida no está en RAM —un fallo de página 缺页—, el SO la lee desde el archivo de intercambio 交换文件 hacia un marco, eliminando otra página si la RAM está llena. Los fallos frecuentes causan thrashing 抖动 (thrashing de disco), donde el SO dedica la mayor parte del tiempo a intercambiar páginas en lugar de realizar trabajo útil.

Páginas lógicas de memoria mapeadas a través de una tabla de páginas a marcos de memoria física no contigua
La paginación mapea cada página de la memoria lógica a un marco de la memoria física

En la segmentación 分段, la memoria se divide en segmentos lógicos de tamaño variable (código, pila, heap), cada uno con sus propios permisos. Muchos sistemas utilizan paginación dentro de segmentos.

Segmentos lógicos de tamaño variable (código, heap, pila) mapeados a través de una tabla de segmentos de tamaños y direcciones de inicio a memoria física
La segmentación mapea segmentos de tamaño variable usando una tabla de mapas de segmento

"Explique qué se entiende por memoria virtual" (tres puntos). El almacenamiento secundario (disco) se utiliza para extender la RAM, de modo que la memoria disponible parece mayor que la memoria física; el espacio de direcciones de un proceso se divide en páginas, y solo las páginas actualmente necesarias se mantienen en RAM mientras el resto esperan en disco; las páginas se intercambian entre RAM y disco según sea necesario, y el SO traduce cada dirección virtual en una física. ¿Por qué lo necesita el SO: los programas en ejecución pueden necesitar más memoria de la instalada; permite que más (o más grandes) programas se ejecuten a la vez; un programa puede ser más grande que la memoria física; la memoria se usa eficientemente porque solo las partes activas de los programas ocupan RAM.

Paginación frente a segmentación: la diferencia que busca el examen. La paginación divide la memoria en bloques de tamaño fijo (páginas y marcos) elegidos por el hardware, sin importar la estructura del programa, y el mapeo es invisible para el programador; la segmentación divide un programa en unidades lógicas de tamaño variable (un procedimiento, una matriz, la pila) cuyos tamaños y límites siguen al programa, de modo que un segmento puede protegerse o compartirse como unidad. "Describa el proceso de segmentación": el programa se divide en segmentos de diferentes tamaños, a cada uno se le asigna un número de segmento; una tabla de segmentos registra dónde comienza cada segmento en la memoria y cuánto mide; una dirección lógica es un número de segmento más un desplazamiento, y el SO suma el desplazamiento a la dirección base del segmento para encontrar la ubicación física.

"Explique qué se entiende por thrashing de disco" y cuándo ocurre. Thrashing de disco 磁盘抖动 es el estado en el que las páginas se intercambian dentro y fuera de RAM con tanta frecuencia que el procesador pasa más tiempo moviendo páginas que ejecutando instrucciones, y el sistema se ralentiza casi hasta detenerse. Ocurre cuando la RAM es demasiado pequeña para las páginas que necesitan los procesos en ejecución (sus conjuntos de trabajo): una página acabada de eliminar se vuelve a necesitar casi de inmediato, por lo que se recupera, lo que elimina otra página que pronto también será necesaria, y así sucesivamente. Demasiados procesos, o un programa que accede a la memoria de forma impredecible, lo provocan; más RAM o menos procesos lo solucionan.

Explorar

Qué ocurre en una falta de página

Recorra paso a paso una falta de página. Cuando el programa accede a una página que no está en la RAM, el SO la obtiene silenciosamente del disco y actualiza la tabla de páginas, haciendo que el programa vea más memoria de la que físicamente existe.

Vocabulario Entrenar
Inglés Chino Pinyin
thrashing/ˈθræʃɪŋ/ 抖动 dǒu dòng
segmentation/ˌseɡmənˈteɪʃn/ 分段 fēn duàn
disk thrashing/dɪsk ˈθræʃɪŋ/ 磁盘抖动 cí pán dǒu dòng
interpreter/ɪnˈtɜːprɪtə/ 解释器 jiě shì qì
compiler/kəmˈpaɪlə/ 编译器 biān yì qì
machine code/məˈʃiːn kəʊd/ 机器码 jī qì mǎ
lexical analysis/ˈleksɪkl əˈnæləsɪs/ 词法分析 cí fǎ fēn xī
16.2

Cómo ejecuta un programa un intérprete

Syllabus
Los candidatos deben ser capaces de: Notas y orientación
Demostrar comprensión de cómo un intérprete puede ejecutar programas sin producir una versión traducida
Demostrar comprensión de las diversas etapas en la compilación de un programa Incluyendo el análisis léxico, análisis sintáctico, generación de código y optimización
Demostrar comprensión de cómo la gramática de un lenguaje puede expresarse mediante diagramas de sintaxis o notación Forma Normal de Backus-Naur (BNF)
Demostrar comprensión de cómo se puede utilizar la Notación Polaca Inversa (NPI) para llevar a cabo la evaluación de expresiones

Fuente: Plan de estudios Cambridge International

Un intérprete 解释器 traduce y ejecuta el código fuente al mismo tiempo. Para cada instrucción lee la línea, realiza análisis léxico y sintáctico, verifica tipos y luego ejecuta la acción, y continúa. Los errores se reportan inmediatamente y generalmente se detiene; no se produce un ejecutable. La traducción se rehace en cada ejecución (más lento), pero ofrece retroalimentación rápida de desarrollo y es portable.

"Explique cómo un intérprete ejecuta un programa sin producir una versión traducida" (tres puntos). El intérprete toma una instrucción (línea) a la vez, la traduce (analiza) y la ejecuta inmediatamente, antes de pasar a la siguiente; no se crea ni almacena una versión traducida de todo el programa, por lo que cada instrucción se traduce cada vez que se ejecuta, incluyendo cada paso por un bucle; si una instrucción contiene un error, la ejecución se detiene allí y se reporta el error. Esto es lo que hace que un intérprete sea bueno para el desarrollo y las pruebas (los errores se encuentran a medida que se alcanzan y un cambio puede probarse de inmediato) pero más lento para ejecutar programas terminados.

16.2

Fases de compilación

Un compilador 编译器 convierte el código fuente en código máquina 机器码 en fases:

  1. análisis léxico — El lexer agrupa caracteres en tokens (palabras clave, identificadores, operadores, literales), descartando espacios en blanco y comentarios.
  2. análisis sintáctico (parsing) — Verifica que los tokens se ajusten a la gramática y construye un árbol de sintaxis abstracta. Un paréntesis faltante genera un error de sintaxis.
  3. análisis semántico — Verifica que el programa tenga sentido (variables declaradas, tipos coincidentes).
  4. generación de código — Recorre el árbol y emite código objetivo, eligiendo registros y distribuciones.
  5. optimización de código — Elimina trabajo redundante, pliega constantes y reordena para la tubería.

La salida es un ejecutable.

Las fases de compilación: el código fuente pasa por análisis léxico (tokens), análisis sintáctico (AST), análisis semántico (verificaciones), generación de código y optimización para producir un ejecutable
Las fases de compilación, desde el código fuente hasta un ejecutable optimizado

El propósito de cada etapa, con las palabras clave. Análisis léxico: elimina espacios en blanco y comentarios; convierte los caracteres del código fuente en tokens (palabras clave, identificadores, operadores, constantes), verificando que cada uno sea válido en el lenguaje; registra los identificadores en la tabla de símbolos. Análisis sintáctico: verifica que la secuencia de tokens obedezca la gramática (reglas de sintaxis) del lenguaje; construye un árbol de análisis (árbol de sintaxis abstracta); informa errores de sintaxis; la verificación de tipos y la comprobación de declaraciones de variables a veces se cuentan aquí como análisis semántico. Generación de código: convierte el árbol validado en código objeto o código máquina (posiblemente mediante código intermedio), asignando memoria y registros. Optimización: hace que el código ejecute más rápido o utilice menos memoria, eliminando instrucciones redundantes, combinando o simplificando cálculos y reorganizando bucles, sin alterar lo que hace el programa. La pregunta de emparejamiento asocia cada etapa con una de estas descripciones.

Explorar

Las fases de la compilación

Recorra paso a paso lo que hace un compilador con su código fuente. Cada fase entrega su salida a la siguiente: los caracteres se convierten en tokens, los tokens en un árbol, y el árbol en código máquina optimizado.

Vocabulario Entrenar
Inglés Chino Pinyin
tokens/ˈtəʊkənz/ 词法单元 cí fǎ dān yuán
syntax analysis (parsing)/ˈsɪntæks əˈnæləsɪs/ 语法分析 yǔ fǎ fēn xī
abstract syntax tree/ˈæbstrækt ˈsɪntæks triː/ 抽象语法树 chōu xiàng yǔ fǎ shù
syntax error/ˈsɪntæks ˈerə/ 语法错误 yǔ fǎ cuò wù
semantic analysis/səˈmæntɪk əˈnæləsɪs/ 语义分析 yǔ yì fēn xī
code generation/kəʊd ˌdʒenəˈreɪʃn/ 代码生成 dài mǎ shēng chéng
code optimisation/kəʊd ˌɒptɪmaɪˈzeɪʃn/ 代码优化 dài mǎ yōu huà
symbol table/ˈsɪmbl ˈteɪbl/ 符号表 fú hào biǎo
grammar/ˈɡræmə/ 文法 wén fǎ
16.2

Gramáticas: BNF y diagramas de sintaxis

Una gramática dice qué secuencias de tokens son programas válidos.

Backus-Naur Form (BNF) es textual. Una regla de producción tiene la forma:

<symbol> ::= alternative1 | alternative2 | ...

Cada alternativa es una secuencia de símbolos terminales (texto literal) y símbolos no terminales (otros nombres de reglas):

<digit>      ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
<identifier> ::= <letter> | <identifier> <letter> | <identifier> <digit>

La tercera regla recursiva expresa "una letra seguida de cualquier número de letras o dígitos". Una instrucción IF:

<if-statement> ::= IF <condition> THEN <statement> ENDIF
                 | IF <condition> THEN <statement> ELSE <statement> ENDIF

Un diagrama de sintaxis (diagrama de vías) muestra lo mismo gráficamente: cajas para no terminales, cajas redondeadas para terminales, flechas para caminos válidos, bucles para repetición. Las dos notaciones son equivalentes. El analizador usa la gramática para decidir si un programa es válido.

Un diagrama de ferrocarril para una asignación: un cuadro rectangular de identificador, un cuadro redondeado de símbolo de asignación, luego un cuadro rectangular de expresión, conectados de izquierda a derecha
Un diagrama de sintaxis (vías) para una instrucción de asignación
Tres diagramas de sintaxis, para una letra, un dígito y un identificador que comienza con una letra y continúa con cualquier número de letras o dígitos, junto a las reglas BNF que expresan exactamente la misma gramática, con ejemplos válidos e inválidos
Un diagrama de sintaxis y una regla BNF dicen lo mismo: una elección se convierte en alternativas separadas por barras, y un bucle se convierte en una regla que se refiere a sí misma

Lectura de los diagramas del examen. Cada diagrama define un no terminal; sigue las flechas desde la entrada hasta la salida, y cada camino que puedas trazar es una cadena válida. Una elección de cajas lado a lado es un conjunto de alternativas; un bucle hacia atrás significa "repetir tantas veces como quieras"; una caja para otro no terminal significa "insertar cualquier cosa que permita esa regla". "Explica por qué la cadena es inválida" pide la regla que rompe, en palabras: 9K es inválido como variable porque el primer carácter debe ser una letra, no un dígito; JJ90 es una contraseña inválida si la regla permite solo una letra antes de los dígitos, o si J no está en el conjunto de letras listadas. Siempre verifica la cadena contra el conjunto de caracteres que el diagrama realmente permite, no contra lo que aceptaría un lenguaje real.

Escritura de BNF a partir de un diagrama. Cada diagrama se convierte en una regla <name> ::= ...; las alternativas se separan por |; una secuencia se escribe un símbolo después del otro; y la repetición se escribe con recursión, porque BNF no tiene símbolo de bucle: "una o más letras" es <word> ::= <letter> | <letter><word>, y "cero o más dígitos después de una letra" es <variable> ::= <letter> | <letter><digits> con <digits> ::= <digit> | <digit><digits>.

Ejemplo resuelto. Completa el BNF para un número de matrícula de vehículo que debe comenzar con dos letras (de A B C) seguidas de uno, dos o tres dígitos (de 0 1 2).

<letter>       ::= A | B | C
<digit>        ::= 0 | 1 | 2
<digits>       ::= <digit> | <digit><digit> | <digit><digit><digit>
<registration> ::= <letter><letter><digits>

AB12 es válido; A12 no lo es (solo una letra); AB1234 no lo es (cuatro dígitos); AD1 no lo es (D no es una letra listada). Se pide añadir una restricción como "el tercer carácter también puede ser un símbolo", añade la alternativa extra a la regla de esa posición únicamente, y define <symbol> con su propia regla.

Ejemplo resuelto. Escribe BNF para una expresión que es una variable, seguida de un operador, seguido de ya sea una variable o un número, donde una variable es una sola letra minúscula de a b c y un operador es + o -.

<variable>   ::= a | b | c
<operator>   ::= + | -
<number>     ::= <digit> | <digit><number>
<expression> ::= <variable><operator><variable> | <variable><operator><number>

La regla recursiva <number> permite cualquier número de dígitos; las dos alternativas de <expression> cubren ambos casos nombrados en la definición. Mantén cada no terminal entre ángulos y cada terminal sin ellos.

Vocabulario Entrenar
Inglés Chino Pinyin
Backus-Naur Form/ˈbækəs nɔː fɔːm/ 巴科斯-诺尔范式 bā kē sī - nuò ěr fàn shì
production rule/prəˈdʌkʃn ruːl/ 产生式 chǎn shēng shì
terminal/ˈtɜːmɪnl/ 终结符 zhōng jié fú
non-terminal/nɒn ˈtɜːmɪnl/ 非终结符 fēi zhōng jié fú
syntax diagram/ˈsɪntæks ˈdaɪəɡræm/ 语法图 yǔ fǎ tú
infix/ˈɪnfɪks/ 中缀 zhōng zhuì
Reverse Polish Notation/rɪˈvɜːs ˈpəʊlɪʃ nəʊˈteɪʃn/ 逆波兰表示法 nì bō lán biǎo shì fǎ
postfix/ˈpəʊstfɪks/ 后缀 hòu zhuì
stack/stæk/ 栈 zhàn
precedence/ˈpresɪdəns/ 优先级 yōu xiān jí
16.2

Notación Polaca Inversa (RPN)

En la notación infija el operador se sitúa entre sus operandos (3 + 4 * 2), requiriendo paréntesis y reglas de precedencia. En la Notación Polaca Inversa (RPN, postfija) el operador sigue a sus operandos (3 4 2 * +), no requiriendo paréntesis.

Conversión de infija a RPN

Usa una pila de operadores. Escanea de izquierda a derecha: emite un operando; para un operador, primero popa cualesquiera operadores apilados de precedencia igual o superior a la salida, luego empújalo; empuja (; sobre ) popa a la salida hasta el correspondiente (. Al final, popa todos los operadores. Ejemplo: (3 + 4) * 2 → 3 4 + 2 *.

Evaluación de RPN

Usa una pila de operandos. Escanea de izquierda a derecha: empuja cada operando; sobre un operador, popa los dos superiores, aplícalo y empuja el resultado. Evaluando 3 4 2 * +:

Token Pila
3 3
4 3, 4
2 3, 4, 2
* 3, 8
+ 11

Resultado: 11. La RPN no requiere paréntesis en el momento de la evaluación y se adapta a una máquina de pila — que es como funcionan la JVM y muchos interpretadores de bytecode.

"Explique por qué se utiliza la RPN para evaluar expresiones" (dos puntos). En la RPN, los operadores aparecen en el orden en que se aplican, por lo que una expresión puede evaluarse mediante un único recorrido de izquierda a derecha sin necesidad de paréntesis ni de reglas de precedencia; por tanto, es más simple y rápida para que el compilador o el intérprete la procesen. "Identifique, con justificación, una estructura de datos adecuada": una pila, porque la evaluación necesita primero los operandos empujados más recientemente (último en entrar, primero en salir): cada operando se empuja, y cada operador extrae los dos superiores, aplica su operación y empuja el resultado. Muestre el contenido de la pila tras cada token cuando se solicite.

Conversión manual de infija a RPN. (1) Encierre completamente la expresión usando las reglas de precedencia; (2) mueva cada operador justo después del paréntesis de cierre correspondiente; (3) elimine los paréntesis. Así, $(a - b) * (a + c) / 7$ se convierte en $((a - b) * (a + c)) / 7$, y luego en a b - a c + * 7 /. Tenga en cuenta que * y / se aplican de izquierda a derecha, por lo que la división es el último operador, no la multiplicación. Más conversiones: $((7 + 3) - (2 * 8)) / 6$ es 7 3 + 2 8 * - 6 /; $(7 - 2 + 8) / (9 - 5)$ es 7 2 - 8 + 9 5 - /; $a * b + b - d + 15$ es a b * b + d - 15 +; $(2 - 6) * (13 + 7) / 5$ es 2 6 - 13 7 + * 5 /.

Conversión de RPN de vuelta a infija. Procese la RPN utilizando una pila de expresiones: empuje cada operando; para cada operador, extraiga dos elementos, escríbalos a ambos lados del mismo entre paréntesis, y empuje el resultado. Así, a b / 4 * a b + - es $((a / b) * 4) - (a + b)$; 5 2 + 9 3 - / 3 * es $((5 + 2) / (9 - 3)) * 3$; b a c - + d b + * c / es $((b + (a - c)) * (d + b)) / c$; a b - c + c a - * d / es $(((a - b) + c) * (c - a)) / d$. Mantenga los paréntesis: eliminarlos puede alterar el significado.

Ejemplo resuelto. Evalúe a b - c d + * e / sabiendo que $a = 17$, $b = 5$, $c = 7$, $d = 3$ y $e = 10$, mostrando la pila.

token acción pila (arriba a la derecha)
a apilar 17 17
b apilar 5 17, 5
- desapilar 5 y 17, apilar $17 - 5$ 12
c apilar 7 12, 7
d apilar 3 12, 7, 3
+ desapilar 3 y 7, apilar $7 + 3$ 12, 10
* desapilar 10 y 12, apilar $12 \times 10$ 120
e apilar 10 120, 10
/ desapilar 10 y 120, apilar $120 / 10$ 12

Resultado 12. El orden de las desapilaciones es importante para - y /: el valor desapilado segundo es el operando izquierdo, por lo que a b - es $a - b$, no $b - a$. Dos más, de la misma manera: d a b + * c a - / con $a = 6, b = 12, c = 15, d = 5$ da como resultado $5 \times (6 + 12) / (15 - 6) = 90 / 9 = 10$; c a - b d + * b c + / con $a = 4, b = 12, c = 24, d = 6$ da como resultado $(24 - 4) \times (12 + 6) / (12 + 24) = 360 / 36 = 10$.

Ejemplo resuelto. Convertir $(A + B) \times (C - D)$ a RPN, luego evaluar $(3 + 4) \times (5 - 2)$. Escanear de izquierda a derecha usando una pila de operadores. Apilar (; emitir A; apilar +; emitir B; al encontrar ), desapilar hasta el par correspondiente (, obteniendo A B + hasta ahora. Apilar ×, y el segundo corchete se comporta de la misma manera, dando como resultado C D -. Al final, desapilar el ⟨×⟩. Resultado: A B + C D - ×. Para evaluar los números, usar una pila de operandos: apilar 3, apilar 4; + desapila ambos y apila 7; apilar 5, apilar 2; - desapila ambos y apila 3; × desapila 7 y 3 y apila 21. Dos factores hacen esto confiable: los operandos mantienen su orden original durante la conversión (solo se mueven los operadores), y cada operador actúa sobre los dos valores inmediatamente inferiores en la pila.

Explorar

Precedencia de operadores — lo que elimina la RPN

En matemáticas infixas ordinarias, × y ÷ tienen mayor precedencia que + y −, por lo que se deben aplicar reglas en el orden correcto. La Notación Polaca Inversa escribe los operandos primero (3 4 2 × + 1 −), fijando el orden para que no sean necesarias reglas de precedencia.

Vocabulario Entrenar
Inglés Chino Pinyin
bytecode/ˈbaɪtkəʊd/ 字节码 zì jié mǎ
16.2

Definiciones aceptadas por el examinador

Una pregunta de definición se califica según un texto fijo. Aprende estas definiciones exactamente, y da solo una respuesta.

Término Definición
multitarea varios procesos mantenidos en memoria a la vez, con el procesador alternando entre ellos para que parezcan ejecutarse simultáneamente
proceso un programa que ha sido cargado en memoria y se está ejecutando (o está listo para serlo)
ejecutando / listo / bloqueado tiene el procesador / esperando por el procesador / no puede continuar hasta que un evento como una E/S se complete
programación decidir qué proceso listo obtendrá el procesador a continuación y durante cuánto tiempo
programación preemptiva el proceso en ejecución puede ser interrumpido y movido al estado listo para que otro proceso se ejecute
memoria virtual usar almacenamiento secundario para extender la RAM, manteniendo solo las páginas actualmente necesarias en memoria física
segmentación dividir la memoria y los programas en páginas de tamaño fijo que se mueven entre disco y RAM según sea necesario
segmentación dividir un programa en segmentos lógicos de tamaño variable, cada uno mapeado a la memoria mediante una tabla de segmentos
thrashing del disco páginas siendo intercambiadas entre RAM y disco tan frecuentemente que se realiza muy poco procesamiento útil
intérprete traduce y ejecuta un programa una instrucción a la vez, sin producir una versión traducida
compilador traduce un programa completo de alto nivel a código máquina (objeto) antes de su ejecución
análisis léxico convierte el código fuente en tokens, eliminando espacios en blanco y comentarios, y construye la tabla de símbolos
análisis sintáctico verifica que los tokens obedezcan la gramática del lenguaje y construye un árbol de análisis
Forma Backus-Naur una notación para la gramática de un lenguaje: reglas de la forma <name> ::= alternatives construidas desde terminales y no terminales
Notación Polaca Inversa una manera de escribir expresiones con cada operador después de sus operandos, de modo que puedan evaluarse con una pila y sin paréntesis
16.2

Consejos para el examen

  • Las preguntas del SO se evalúan sobre mecanismos nombrados: programación, gestión de memoria, bufferización y spooling de E/S, gestión de archivos; para la interfaz, nombres de archivo no direcciones, clics no comandos, controladores, GUI.
  • Estados del proceso con sus transiciones y la razón de cada una; rutinas de programación como función más beneficio más desventaja; el kernel guarda el estado, identifica la interrupción, la atiende, la restaura.
  • Memoria virtual: el disco extiende la RAM, páginas intercambiadas, traducción de direcciones; la segmentación es de tamaño fijo e invisible, la segmentación es de tamaño variable y lógica; el thrashing es intercambiar en lugar de trabajar.
  • Intérprete: una instrucción a la vez, traducido luego ejecutado, nada almacenado. Etapas del compilador: tokens y tabla de símbolos, gramática y árbol de análisis, código, optimización.
  • BNF: una regla por diagrama, | para elección, recursión para repetición, terminales desnudos y no terminales entre ángulos. Decir qué regla rompe una cadena.
  • RPN: operadores después de operandos, evaluar con una pila, mostrar cada paso; convertir completamente entre paréntesis; al convertir de vuelta, mantener los paréntesis.

Errores comunes

  • Describir la multitarea como "ejecutar varios programas al mismo tiempo" sin mencionar que el procesador alterna entre ellos.
  • Enviar un proceso bloqueado directamente al estado ejecutando, o dar "se acabó el intervalo de tiempo" como razón para pasar de ejecutando a bloqueado.
  • Confundir shortest job first (no preemptivo) con shortest remaining time (preemptivo), o round robin con prioridad.
  • Definir la memoria virtual como "usar el disco duro como RAM" sin mencionar que las páginas son intercambiadas.
  • Decir que un intérprete "convierte el programa a código máquina y luego lo ejecuta"; eso es un compilador.
  • Colocar la verificación sintáctica en el análisis léxico, o la optimización antes de la generación de código en la pregunta de emparejamiento.
  • Escribir la repetición en BNF como <letter>* o con puntos suspensivos; usar recursión. Dejar fuera los paréntesis angulares de los no terminales.
  • Invertir los operandos de - o / al evaluar RPN, o escribir la RPN de $a * b + c$ como a b c + *.
Vocabulario Entrenar
Inglés Chino Pinyin
kernel/ˈkɜːnl/ 内核 nèi hé
interrupt handler/ˈɪntərʌpt ˈhændlə/ 中断处理程序 zhōng duàn chǔ lǐ chéng xù
interrupt handling/ˈɪntərʌpt ˈhændlɪŋ/ 中断处理 zhōng duàn chǔ lǐ
inter-process communication/ˈɪntə ˈprəʊses kəˌmjuːnɪˈkeɪʃn/ 进程间通信 jìn chéng jiān tōng xìn
pipes/paɪps/ 管道 guǎn dào
shared memory/ʃeəd ˈmeməri/ 共享内存 gòng xiǎng nèi cún
virtual address space/ˈvɜːtʃuːəl əˈdres speɪs/ 虚拟地址空间 xū nǐ dì zhǐ kōng jiān
pages/ˈpeɪdʒɪz/ 页 yè
frames/freɪmz/ 页框 yè kuāng
page fault/peɪdʒ fɒlt/ 缺页 quē yè
swap file/swɒp faɪl/ 交换文件 jiāo huàn wén jiàn

Lecciones interactivas sobre este tema

Trátalo paso a paso, con ejercicios de verificación instantánea.

Exámenes Anteriores

Más temas en A-Level Ciencias de la Computación

Iniciar sesión o crear cuenta

IGCSE, A-Level & AP