|
| 1 | +<!DOCTYPE html> |
| 2 | +<html lang="en"> |
| 3 | +<head> |
| 4 | +<meta charset="utf-8"> |
| 5 | +<title>Garbage Collection Quiz</title> |
| 6 | +<meta name="viewport" content="width=device-width,initial-scale=1"> |
| 7 | +<style> |
| 8 | + :root{ |
| 9 | + --ok:#4caf50; --bad:#f44336; --border:#bbb; |
| 10 | + --bg:#fafafa; --fg:#222; --accent:#1565c0; |
| 11 | + } |
| 12 | + body{font-family:system-ui,Segoe UI,Roboto,sans-serif;margin:0;background:var(--bg);color:var(--fg);} |
| 13 | + header{padding:1rem;background:var(--accent);color:#fff;text-align:center;} |
| 14 | + main{padding:1rem;max-width:820px;margin:auto;} |
| 15 | + h2{margin-top:2rem;color:var(--accent);} |
| 16 | + .q{padding:1rem;border:1px solid var(--border);border-radius:6px;margin-bottom:.8rem;background:#fff;} |
| 17 | + .q.correct{border-color:var(--ok);background:#f1f8f4;} |
| 18 | + .q.wrong {border-color:var(--bad);background:#fef5f5;} |
| 19 | + label{display:block;padding:.3rem 0;cursor:pointer;} |
| 20 | + button{padding:.6rem 1rem;margin:1.5rem 0;font-size:1rem;border:none;border-radius:4px;background:var(--accent);color:#fff;cursor:pointer;} |
| 21 | + button:hover:not(:disabled){background:#0d47a1;} |
| 22 | + button:disabled{opacity:.6;cursor:not-allowed;} |
| 23 | + #result{font-weight:bold;font-size:1.1rem;margin-top:1rem;padding:1rem;border-radius:4px;} |
| 24 | + #result.show{background:#e3f2fd;border:1px solid var(--accent);} |
| 25 | + footer{padding:1rem;text-align:center;font-size:.85rem;color:#555;} |
| 26 | + @media(max-width:500px){body{font-size:15px;}} |
| 27 | +</style> |
| 28 | +</head> |
| 29 | +<body> |
| 30 | +<header><h1>Garbage Collection – Self-Check Quiz</h1></header> |
| 31 | +<main> |
| 32 | + <section id="trueFalse"><h2>True / False</h2></section> |
| 33 | + <section id="mcq"><h2>Multiple Choice</h2></section> |
| 34 | + <button id="submitBtn">Check Answers</button> |
| 35 | + <div id="result"></div> |
| 36 | +</main> |
| 37 | +<footer>Based on "Garbage Collection" chapter. © 2026</footer> |
| 38 | + |
| 39 | +<script> |
| 40 | +const tfWrap = document.getElementById('trueFalse'); |
| 41 | +const mcqWrap = document.getElementById('mcq'); |
| 42 | +const submitBtn = document.getElementById('submitBtn'); |
| 43 | +const resultBox = document.getElementById('result'); |
| 44 | + |
| 45 | +// build true/false element |
| 46 | +function buildTF(q,i){ |
| 47 | + const div=document.createElement('div'); |
| 48 | + div.className='q'; |
| 49 | + div.dataset.correct=q.answer; |
| 50 | + div.innerHTML=`<strong>T/F ${i+1}.</strong> ${q.question} |
| 51 | + <label><input type="radio" name="tf${i}" value="true">True</label> |
| 52 | + <label><input type="radio" name="tf${i}" value="false">False</label>`; |
| 53 | + return div; |
| 54 | +} |
| 55 | + |
| 56 | +// build multiple choice element |
| 57 | +function buildMCQ(q,i){ |
| 58 | + const div=document.createElement('div'); |
| 59 | + div.className='q'; |
| 60 | + div.dataset.correct=q.answer; // store index |
| 61 | + let optionsHTML=''; |
| 62 | + q.options.forEach((opt,idx)=>{ |
| 63 | + optionsHTML+=`<label><input type="radio" name="mc${i}" value="${idx}">${opt}</label>`; |
| 64 | + }); |
| 65 | + div.innerHTML=`<strong>Q${i+1}.</strong> ${q.question}<br>${optionsHTML}`; |
| 66 | + return div; |
| 67 | +} |
| 68 | + |
| 69 | +// evaluate answers |
| 70 | +function grade(){ |
| 71 | + let correct=0, total=0; |
| 72 | + document.querySelectorAll('.q').forEach(div=>{ |
| 73 | + total++; |
| 74 | + const sel = div.querySelector('input[type=radio]:checked'); |
| 75 | + if(sel && (sel.value==div.dataset.correct)){ |
| 76 | + correct++; |
| 77 | + div.classList.add('correct'); |
| 78 | + div.classList.remove('wrong'); |
| 79 | + }else{ |
| 80 | + div.classList.add('wrong'); |
| 81 | + div.classList.remove('correct'); |
| 82 | + } |
| 83 | + }); |
| 84 | + resultBox.textContent=`Score: ${correct} / ${total} (${Math.round(correct/total*100)}%)`; |
| 85 | + resultBox.className='show'; |
| 86 | + submitBtn.disabled=true; |
| 87 | +} |
| 88 | + |
| 89 | +// Quiz data embedded directly |
| 90 | +const quizData = { |
| 91 | + "trueFalse": [ |
| 92 | + { "question": "In a mark-and-sweep garbage collector, the roots of the object graph are the program variables currently in scope.", "answer": "true" }, |
| 93 | + { "question": "During mark-and-sweep, the sweep phase reclaims every node that was not marked in the mark phase.", "answer": "true" }, |
| 94 | + { "question": "A recursive depth-first search used for marking may require more stack space than the entire heap in the worst case.", "answer": "true" }, |
| 95 | + { "question": "Pointer reversal can eliminate the need for an auxiliary stack during depth-first marking.", "answer": "true" }, |
| 96 | + { "question": "The sweep phase of mark-and-sweep also clears the mark bits in preparation for the next collection.", "answer": "true" }, |
| 97 | + { "question": "Reference counting can reclaim garbage cycles automatically.", "answer": "false" }, |
| 98 | + { "question": "Updating reference counts adds only negligible run-time cost to pointer assignments.", "answer": "false" }, |
| 99 | + { "question": "Copying garbage collection eliminates fragmentation by moving live objects into a contiguous region.", "answer": "true" }, |
| 100 | + { "question": "Cheney's copying algorithm relies on an explicit stack to perform breadth-first traversal.", "answer": "false" }, |
| 101 | + { "question": "After a copying collection, the entire old from-space is unreachable and may be reused wholesale.", "answer": "true" }, |
| 102 | + { "question": "Breadth-first copying normally gives better locality of reference than depth-first copying.", "answer": "false" }, |
| 103 | + { "question": "Generational collectors are built on the empirical observation that most objects die young.", "answer": "true" }, |
| 104 | + { "question": "A simple copying collector usually divides the heap into two semi-spaces of equal size.", "answer": "true" }, |
| 105 | + { "question": "For mark-and-sweep, the amortized cost per allocated word decreases as the heap size grows relative to live data.", "answer": "true" }, |
| 106 | + { "question": "External fragmentation occurs when free blocks are larger than the requested allocation size.", "answer": "false" }, |
| 107 | + { "question": "Using an array of freelists keyed by block size can speed up allocation in a mark-and-sweep collector.", "answer": "true" }, |
| 108 | + { "question": "The Forward operation in a copying collector installs a forwarding pointer inside the original object.", "answer": "true" }, |
| 109 | + { "question": "Recursive DFS is always preferred over an explicit stack because it is simpler and uses less memory.", "answer": "false" }, |
| 110 | + { "question": "With reference counting, the compiler must insert additional code at every pointer assignment.", "answer": "true" }, |
| 111 | + { "question": "Generational garbage collectors never require write barriers to track pointers from old to young generations.", "answer": "false" } |
| 112 | + ], |
| 113 | + "multipleChoice": [ |
| 114 | + { |
| 115 | + "question": "Which phase of a mark-and-sweep collector is responsible for linking reclaimed blocks into the freelist?", |
| 116 | + "options": [ |
| 117 | + "A. Mark phase", |
| 118 | + "B. Sweep phase", |
| 119 | + "C. Forward phase", |
| 120 | + "D. Copy phase" |
| 121 | + ], |
| 122 | + "answer": "1" |
| 123 | + }, |
| 124 | + { |
| 125 | + "question": "What primary data structure does Cheney's algorithm use to avoid an explicit stack?", |
| 126 | + "options": [ |
| 127 | + "A. The call stack", |
| 128 | + "B. A linked list inside each object", |
| 129 | + "C. The to-space region between 'scan' and 'next'", |
| 130 | + "D. An external bitmap" |
| 131 | + ], |
| 132 | + "answer": "2" |
| 133 | + }, |
| 134 | + { |
| 135 | + "question": "In the cost formula c₁R + c₂H for mark-and-sweep, the term R denotes:", |
| 136 | + "options": [ |
| 137 | + "A. Heap size", |
| 138 | + "B. Size of reachable data", |
| 139 | + "C. Number of roots", |
| 140 | + "D. Free list length" |
| 141 | + ], |
| 142 | + "answer": "1" |
| 143 | + }, |
| 144 | + { |
| 145 | + "question": "Pointer reversal temporarily stores which of the following in an object's own fields?", |
| 146 | + "options": [ |
| 147 | + "A. Mark bits", |
| 148 | + "B. Reference counts", |
| 149 | + "C. Stack links for DFS", |
| 150 | + "D. Allocation timestamps" |
| 151 | + ], |
| 152 | + "answer": "2" |
| 153 | + }, |
| 154 | + { |
| 155 | + "question": "Which problem prevents pure reference counting from reclaiming all garbage?", |
| 156 | + "options": [ |
| 157 | + "A. Memory leaks", |
| 158 | + "B. Cyclic data structures", |
| 159 | + "C. Fragmentation", |
| 160 | + "D. Stack overflow" |
| 161 | + ], |
| 162 | + "answer": "1" |
| 163 | + }, |
| 164 | + { |
| 165 | + "question": "External fragmentation is best described as:", |
| 166 | + "options": [ |
| 167 | + "A. Wasted space inside an allocated block", |
| 168 | + "B. Free space scattered in blocks too small for new allocations", |
| 169 | + "C. Copying overhead between semi-spaces", |
| 170 | + "D. Unused bits in a mark table" |
| 171 | + ], |
| 172 | + "answer": "1" |
| 173 | + }, |
| 174 | + { |
| 175 | + "question": "The main advantage of a generational collector is that it:", |
| 176 | + "options": [ |
| 177 | + "A. Requires no write barriers", |
| 178 | + "B. Focuses collection effort where most garbage is expected", |
| 179 | + "C. Eliminates the need for a freelist", |
| 180 | + "D. Works only with reference counting" |
| 181 | + ], |
| 182 | + "answer": "1" |
| 183 | + }, |
| 184 | + { |
| 185 | + "question": "In a simple two-space copying collector, allocation of a new object typically involves:", |
| 186 | + "options": [ |
| 187 | + "A. Searching the freelist for a block of exact size", |
| 188 | + "B. Incrementing a 'next' pointer in to-space", |
| 189 | + "C. Decrementing reference counts", |
| 190 | + "D. Scanning the entire heap for free space" |
| 191 | + ], |
| 192 | + "answer": "1" |
| 193 | + }, |
| 194 | + { |
| 195 | + "question": "Which field is often repurposed as the forwarding pointer in a copied object?", |
| 196 | + "options": [ |
| 197 | + "A. The last field", |
| 198 | + "B. The first field", |
| 199 | + "C. A hidden header word", |
| 200 | + "D. A newly allocated side table entry" |
| 201 | + ], |
| 202 | + "answer": "1" |
| 203 | + }, |
| 204 | + { |
| 205 | + "question": "Suppose a mark-and-sweep heap has H words, of which R are reachable. The amount of memory reclaimed after a collection is:", |
| 206 | + "options": [ |
| 207 | + "A. R words", |
| 208 | + "B. H words", |
| 209 | + "C. H − R words", |
| 210 | + "D. H / 2 words" |
| 211 | + ], |
| 212 | + "answer": "2" |
| 213 | + }, |
| 214 | + { |
| 215 | + "question": "Which optimization can reduce the run-time overhead of reference counting?", |
| 216 | + "options": [ |
| 217 | + "A. Write barriers", |
| 218 | + "B. Data-flow aggregation of increments/decrements", |
| 219 | + "C. Breadth-first traversal", |
| 220 | + "D. Semi-space allocation" |
| 221 | + ], |
| 222 | + "answer": "1" |
| 223 | + }, |
| 224 | + { |
| 225 | + "question": "The remembered set in a generational collector records:", |
| 226 | + "options": [ |
| 227 | + "A. All live objects in the youngest generation", |
| 228 | + "B. Pointers from older to younger generations", |
| 229 | + "C. Sizes of free blocks", |
| 230 | + "D. Reference counts of old objects" |
| 231 | + ], |
| 232 | + "answer": "1" |
| 233 | + }, |
| 234 | + { |
| 235 | + "question": "Cheney's algorithm moves the 'scan' pointer forward until:", |
| 236 | + "options": [ |
| 237 | + "A. It reaches the end of to-space", |
| 238 | + "B. All objects have been marked", |
| 239 | + "C. 'scan' equals 'next'", |
| 240 | + "D. The freelist is empty" |
| 241 | + ], |
| 242 | + "answer": "2" |
| 243 | + }, |
| 244 | + { |
| 245 | + "question": "Which of the following is an internal fragmentation problem?", |
| 246 | + "options": [ |
| 247 | + "A. Free space cannot satisfy a request because blocks are too small", |
| 248 | + "B. Extra unused space exists inside an allocated block", |
| 249 | + "C. Heap contains unreachable cycles", |
| 250 | + "D. The mark stack overflows" |
| 251 | + ], |
| 252 | + "answer": "1" |
| 253 | + }, |
| 254 | + { |
| 255 | + "question": "In Algorithm 13.8, what triggers the creation of a forwarding pointer?", |
| 256 | + "options": [ |
| 257 | + "A. Detecting a cycle", |
| 258 | + "B. Copying an object to to-space for the first time", |
| 259 | + "C. Incrementing reference count to zero", |
| 260 | + "D. Encountering an external pointer" |
| 261 | + ], |
| 262 | + "answer": "1" |
| 263 | + }, |
| 264 | + { |
| 265 | + "question": "Which parameter most directly influences locality of reference in a copying collector?", |
| 266 | + "options": [ |
| 267 | + "A. Heap size H", |
| 268 | + "B. Choice between breadth-first and depth-first copy order", |
| 269 | + "C. Number of generations", |
| 270 | + "D. Reference count update frequency" |
| 271 | + ], |
| 272 | + "answer": "1" |
| 273 | + }, |
| 274 | + { |
| 275 | + "question": "The semi-depth-first variant of copying attempts to improve locality by:", |
| 276 | + "options": [ |
| 277 | + "A. Using a bitmap instead of forwarding pointers", |
| 278 | + "B. Copying a child object immediately after its parent when possible", |
| 279 | + "C. Doubling the size of to-space", |
| 280 | + "D. Avoiding any pointer reversal" |
| 281 | + ], |
| 282 | + "answer": "1" |
| 283 | + }, |
| 284 | + { |
| 285 | + "question": "Mark-and-sweep collectors often organize free blocks by size using:", |
| 286 | + "options": [ |
| 287 | + "A. A single FIFO queue", |
| 288 | + "B. An array of size-segregated freelists", |
| 289 | + "C. A binary search tree keyed by address", |
| 290 | + "D. A hash table keyed by reference count" |
| 291 | + ], |
| 292 | + "answer": "1" |
| 293 | + }, |
| 294 | + { |
| 295 | + "question": "Write barriers in generational collectors are primarily needed to:", |
| 296 | + "options": [ |
| 297 | + "A. Prevent concurrent mutations", |
| 298 | + "B. Detect pointer updates from old to young objects", |
| 299 | + "C. Update reference counts lazily", |
| 300 | + "D. Split oversized free blocks" |
| 301 | + ], |
| 302 | + "answer": "1" |
| 303 | + }, |
| 304 | + { |
| 305 | + "question": "If a copying collector's semi-spaces are each 32 MB and live data occupy 12 MB, how many megabytes are available for new allocations before the next collection?", |
| 306 | + "options": [ |
| 307 | + "A. 12 MB", |
| 308 | + "B. 20 MB", |
| 309 | + "C. 32 MB", |
| 310 | + "D. 52 MB" |
| 311 | + ], |
| 312 | + "answer": "1" |
| 313 | + } |
| 314 | + ] |
| 315 | +}; |
| 316 | + |
| 317 | +// Build UI with embedded data |
| 318 | +quizData.trueFalse.forEach((q,i)=>tfWrap.appendChild(buildTF(q,i))); |
| 319 | +quizData.multipleChoice.forEach((q,i)=>mcqWrap.appendChild(buildMCQ(q,i))); |
| 320 | +submitBtn.addEventListener('click',grade); |
| 321 | +</script> |
| 322 | +</body> |
| 323 | +</html> |
0 commit comments