Operating Systems Module 7
Memory management: addresses, segmentation and paging interview questions
Interview questions on “Memory management: addresses, segmentation and paging”: warm-ups, then what each harder question tests and how a good answer starts.
Warm-up questions
Short questions with short answers, each answered in full.
-
Fresher to mid
What is the difference between a logical address and a physical address, and what translates one into the other?
-
Fresher to mid
What is the difference between internal and external fragmentation? Give an example of each.
Answered in the lesson Contiguous allocation and fragmentation
-
Fresher to mid
What does a segment table entry hold, and what happens when a program uses an offset past its segment's limit?
-
Fresher to mid
How does the MMU split a virtual address into a page number and an offset, and how does it form the physical address?
Answered in the lesson Paging: pages, frames and page tables
-
Fresher to mid
How does a buddy allocator split and merge blocks, and how does it find a block's buddy?
Answered in the lesson Allocating memory: buddy, slab and malloc
Questions with model answers
What each question tests, the first step of a good answer and the follow-ups to expect.
-
Mid to senior
A program that runs on your laptop fails to start on a production Linux server, which reports that a shared library cannot be found. How does the dynamic linker look for libraries, and how would you find and fix the cause?
- What it tests
- How ld.so finds shared libraries, reading a binary's dependencies with the right tools, and fixing the build or the deployment rather than hiding the symptom.
- First step
- Read what the program asks for before changing anything: readelf -d lists its DT_NEEDED names and any RPATH or RUNPATH, and ldd shows how each one resolves on this server. Then compare with the laptop: a missing package, a different version in the library's name, or a library that was found there only through LD_LIBRARY_PATH.
- Follow-ups
-
- Why is exporting LD_LIBRARY_PATH in the service's start script a poor fix?
- The library is there, but the error names a symbol version such as GLIBC_2.38. What now?
- How would you catch this before a release reaches the servers?
From the lesson Linking, loading and address binding
Model answer, Pro. Model answers open with any pass; prices are in the notice on this page.Opening the model answers with your pass…
Model answers open with any MySmartCoPilot pass.
- Pro pass · 1 week₹79$2.99
- 30 days₹179$5.99
- 1 year₹1,699$45
One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.
Passes can’t be bought right now, so the model answers can’t be opened at the moment. If you have a pass, enter your licence key.
It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).
In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to staff
Your team ships a command-line tool to thousands of Linux machines that you do not control. Would you link it statically or dynamically? Argue from start-up time, file size, security fixes and what can break on the machines.
- What it tests
- Weighing static against dynamic linking by their real consequences: drifting dependencies, who ships security fixes, shared memory pages, start-up work and the parts of the C library that resist static linking.
- First step
- Start from what the machines share and what they do not. A dynamic build depends on each machine's libraries and their versions; a static build carries its own copies. Then price each choice: who ships the fix when a library has a vulnerability, how large the file gets, whether processes share pages, and which libraries are hard to link statically.
- Follow-ups
-
- A security fix lands in the compression library your tool uses. What happens in each case?
- Fifty different tools on one machine use the same library. How does memory use differ between the two builds?
- What does a static binary lose for address space layout randomisation, and what restores it?
From the lesson Linking, loading and address binding
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
A long-running service keeps about 2 GB of live objects, yet its resident memory grows from 3 GB to 6 GB over a week and never falls back. A heap profile shows no leak. How could fragmentation explain this, and what would you check and change?
- What it tests
- Telling fragmentation from a leak, knowing why an allocator keeps free memory it cannot use, and choosing the measurements and allocation changes that confirm and fix it.
- First step
- Compare three numbers over time: live bytes from the heap profile, bytes the allocator holds from the system, and resident memory. A flat first number with a growing second one means the allocator keeps free memory it cannot hand out or give back. Then look at the allocations: long-lived and short-lived blocks of varied sizes mixed together are the usual cause.
- Follow-ups
-
- Why does the memory not go back to the system when the objects are freed?
- What would you change in how the code allocates?
- When would you switch to another allocator, and how would you judge the result?
From the lesson Contiguous allocation and fragmentation
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to staff
A medical device without an MMU must run for five years without a restart, and it allocates and frees network buffers of five different sizes all day. Would you give it a first-fit heap? Explain the risk and design the allocation.
- What it tests
- Seeing that fragmentation, not a leak, threatens a long-running system without an MMU, and replacing a general heap with bounded pools of fixed sizes chosen from the workload.
- First step
- Name the failure first: without an MMU there is no paging, and nobody compacts the heap, so external fragmentation can only grow, and a heap that works for a week may refuse a buffer after a year with plenty of memory free. Then work out the worst case the design must hold: how many buffers of each size can be live at the same moment.
- Follow-ups
-
- How do you size each pool, and what happens when one runs out?
- How would you show on a test bench that the design does not fragment?
- What changes if one buffer size takes most of the traffic during a burst?
From the lesson Contiguous allocation and fragmentation
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Senior to staff
An allocator manages a 1 GiB region of long-lived objects, and requests start failing with 300 MiB free in small holes. You could stop the program and compact the region. How would you decide whether compaction pays, with numbers?
- What it tests
- Estimating compaction's cost from the bytes it moves and the copy speed, comparing it with cheaper ways to make one large hole, and knowing what the program must provide before any object can move.
- First step
- Estimate the cost before deciding. Compaction copies every live block above the first hole, so it can move most of the 724 MiB in use. Measure the copy speed of the machine, turn the bytes into a pause, and compare that pause with the cost of the failures and with moving only the few blocks that make one hole large enough.
- Follow-ups
-
- What must the program provide so that its objects can move?
- How would you avoid one long pause?
- When is refusing the request the better answer?
From the lesson Contiguous allocation and fragmentation
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
A design needs read-only code shared by many processes, private writable data and a stack that grows. Compare providing this with segments and with pages: protection, sharing, growth and the memory each one wastes.
- What it tests
- Knowing what segments and pages each make easy, where each wastes memory, and why systems settled on pages with rights on every page.
- First step
- Take the requirements one at a time and say what each mechanism keeps per unit: a segment has one base, limit and set of rights for a whole part of the program, a page the same for every fixed-size piece. Then ask what each costs when a part grows, and after memory has been in use for months.
- Follow-ups
-
- How does each design waste memory, and how much?
- What happens to a growing stack under each?
- Which would you choose for a small embedded system, and why?
From the lesson Segmentation and segment tables
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Senior to staff
Two threads of one process run the same machine code, which reads and writes a variable declared thread_local, yet each sees its own value. How does each thread reach its own copy on x86-64 Linux, and why must a program not set this up by hand?
- What it tests
- Following a thread-local access from the instruction to its copy, knowing which state the kernel switches with each thread, and respecting who owns that state.
- First step
- Start from what differs between the threads when they run the same instruction: not the code, and not the offset written in it. Something the kernel saves and restores with each thread must lead each one to its own block of thread data. Name that state, then follow one access from the instruction to the copy.
- Follow-ups
-
- What changes when the variable lives in a shared library loaded with dlopen?
- Why must that state be switched on every context switch?
- How does a 64-bit Arm processor do the same?
From the lesson Segmentation and segment tables
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
Linux on x86-64 hardly uses segments, yet a bad pointer still ends a program with a segmentation fault. What actually traps, what does the kernel do, and how would you find the bug?
- What it tests
- Connecting the name SIGSEGV to the checks page tables make, telling a missing mapping from a forbidden access, and using the signal's information and the right tools to locate the access.
- First step
- Separate the name from the mechanism. The MMU traps on an access the page tables do not allow, and the kernel turns that fault into the signal SIGSEGV for the process. Then say which of the two cases it was, an address with no mapping or an access the mapping forbids, because they point at different bugs.
- Follow-ups
-
- How do you get the faulting address and the code that made the access?
- Why might the same bug crash on one run and not on another?
- When does the kernel send SIGBUS instead?
From the lesson Segmentation and segment tables
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
A teammate proposes a single-level page table for a 64-bit system with 48-bit virtual addresses and 4 KiB pages. Work out its size, explain why it fails, and describe what real systems do instead.
- What it tests
- Computing a page table's size from the address width, the page size and the entry size, and seeing why sparse address spaces need tables that cover only what is mapped.
- First step
- Count before judging. 48 bits of address with 12 bits of offset leave 36 bits of page number, so the table has 2³⁶ entries, and at 8 bytes each that is 2³⁹ bytes. Compare that with the memory of the machine, and with how much of its address space a process really maps.
- Follow-ups
-
- How large would the table be with 16 KiB or 64 KiB pages?
- How does a table with several levels avoid the cost for a sparse address space?
- What does each extra level add to the cost of a translation?
From the lesson Paging: pages, frames and page tables
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Senior to staff
You are choosing the base page size for a new operating system for phones and servers on 64-bit Arm, which can use 4 KiB, 16 KiB or 64 KiB pages. What do you weigh, with numbers, and what would you pick?
- What it tests
- Weighing page-table size, the memory each TLB entry covers and internal fragmentation with real numbers, together with the cost to software of a page size other than 4 KiB.
- First step
- List what the page size changes: entries per gigabyte mapped, the memory each TLB entry covers, the memory lost in the last page of every region, and how much existing software assumes 4 KiB. Then put numbers on each for the workloads you expect, such as many small processes on a phone and large heaps on a server.
- Follow-ups
-
- What does Android's move to 16 KB pages show?
- How do huge pages change the decision?
- What breaks in existing programs when the page size changes?
From the lesson Paging: pages, frames and page tables
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
A database that maps files into memory, written on x86-64 Linux, fails its tests on an Apple silicon Mac: some mprotect calls return EINVAL, and a guard page no longer catches a buffer overflow. What assumption is wrong, and how do you fix the code?
- What it tests
- Recognising a hard-coded page size, knowing that alignment and protection work in whole pages, and reading the size at run time.
- First step
- Look for 4096 written into the code, or a page size fixed when the program was compiled, and compare it with the size this Mac reports, 16 KiB. Then take each failing call in turn: what mprotect requires of the address it is given, and how much memory a protection change really covers when pages are four times larger than the code assumes.
- Follow-ups
-
- How do you read the page size correctly on each system?
- Why might the guard page protect nothing at all, without any error?
- How would you catch this in tests on a machine with 4 KiB pages?
From the lesson Paging: pages, frames and page tables
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
A service keeps millions of 600-byte records in memory, allocated from an allocator that rounds every request up to a power of two. How much memory does it waste, and what would you change, with numbers?
- What it tests
- Computing internal fragmentation from size classes, and choosing between size classes, a dedicated pool or slab of exact slots, and a change to the record itself.
- First step
- Work out what one record costs: 600 bytes round up to 1,024, so 424 bytes, 41 % of every block, are unused. Then scale it to the number of records, and compare it with a pool whose slots are exactly 600 bytes, cut from pages of 4 KiB or 16 KiB.
- Follow-ups
-
- How much does a pool of 600-byte slots leave unused per page?
- What if the records grow to 650 bytes next year?
- When is shrinking the record the better answer?
From the lesson Allocating memory: buddy, slab and malloc
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
A Linux service built with glibc allocates and frees 256 KiB buffers thousands of times a second, and profiles show time in mmap, munmap and page faults. What is malloc doing with those buffers, and what would you change?
- What it tests
- Knowing glibc's mmap threshold, its dynamic adjustment and what switches it off, and the costs of mapping, unmapping and faulting in fresh pages.
- First step
- Start from the threshold: requests of 128 KiB or more get a mapping of their own by default, and freeing one unmaps it, so every buffer would cost an mmap, a munmap and a page fault per page touched. Then check why the threshold did not move: mallopt(3) raises it when such a block is freed, unless a tuning parameter is set.
- Follow-ups
-
- Why would the threshold stay at 128 KiB in this service?
- What does each munmap cost beyond the system call?
- Which fix keeps the memory low as well as the time?
From the lesson Allocating memory: buddy, slab and malloc
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 4 minutes
-
Mid to staff
A C service sometimes returns corrupted values and crashes once a week, and you suspect a use after free in your own code. How would you find it, and how would you make sure it does not come back?
- What it tests
- Using AddressSanitizer and the right tests to make a rare memory bug fail at once, reading its report, fixing the ownership problem and keeping the check in the build.
- First step
- Make the bug deterministic before you look for it: build the service and its tests with -fsanitize=address, run the tests and a replay of real traffic, and let the first invalid access stop the program with a report that names the read, the free and the allocation.
- Follow-ups
-
- What does each part of the report tell you?
- How would you fix the code so the same kind of bug cannot recur?
- Why might the bug not show up under AddressSanitizer at first?
From the lesson Allocating memory: buddy, slab and malloc
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 4 minutes
All Operating Systems interview questions · The Operating Systems track