InterviewDB
Question
Build Architect: Design a Dependency-Aware Build System
phone
Question Details
Problem
Design a build system that compiles targets in dependency order, using cached results where possible. Each target has a list of source files and dependencies on other targets. A target needs rebuilding if any source file or dependency has changed since the last build.
python
class BuildSystem:
def add_target(
self,
name: str,
sources: list[str],
deps: list[str],
build_fn: callable
) -> None:
def build(self, target: str) -> str:
**returns** build artifact path
def invalidate(self, source_file: str) -> None: # mark file as changed
Example
build.add_target("libfoo", sources=["foo.c"], deps=[], build_fn=compile_c)
build.add_target("app", sources=["main.c"], deps=["libfoo"], build_fn=link)
build.build("app") # compiles libfoo, then app
build.build("app") # fully cached: nothing recompiles
build.invalidate("foo.c")
build.build("app") # recompiles libfoo AND app (transitive invalidation)
Follow-ups
- How do you detect circular dependencies?
- Which targets can be built in parallel? How do you schedule them?
- How would you implement content-based caching (hash of inputs) vs. timestamp-based?
Full Details
Problem
Design a build system that compiles targets in dependency order, using cached results where possible. Each target has a list of source files and dependencies on other targets. A target needs rebuilding if any source file or dependency has changed since the last build.
python
class BuildSystem:
def add_target(
self,
name: str,
sources: list[str],
deps: list[str],
build_fn: callable
) -> None:
def build(self, target: str) -> str:
**returns** build artifact path
def invalidate(self, source_file: str) -> None: # mark file as changed
Example
build.add_target("libfoo", sources=["foo.c"], deps=[], build_fn=compile_c)
build.add_target("app", sources=["main.c"], deps=["libfoo"], build_fn=link)
build.build("app") # compiles libfoo, then app
build.build("app") # fully cached: nothing recompiles
build.invalidate("foo.c")
build.build("app") # recompiles libfoo AND app (transitive invalidation)
Follow-ups
- How do you detect circular dependencies?
- Which targets can be built in parallel? How do you schedule them?
- How would you implement content-based caching (hash of inputs) vs. timestamp-based?
Free preview. Unlock all questions →
Topics
Coding
Onsite
Phone