Angular 核心概念面试题

本章聚焦面试高频三大核心:依赖注入(DI)、组件通信、生命周期钩子,并解析大厂公司侧重点。先看常见追问脉络,再逐个击破。

依赖注入原理 组件通信方式 生命周期顺序 公司关注点 优化实践 如何实现依赖注入? 有哪些通信方式? 钩子执行顺序? 公司最看重什么? 如何优化性能?
📌 章节重点: 回答“依赖注入”需讲清 @Injectable、providedIn、层次注入;组件通信掌握 @Input/@Output、Service、ng-content;生命周期熟知 ngOnChanges → ngOnInit → ngDoCheck → ngAfterContentInit → ngAfterViewInit → ngOnDestroy 顺序及变更检测触发时机。

Q1:Angular 依赖注入是如何工作的?请举例说明层级注入。

考察点是否理解 DI 容器、注入器树、层级作用域;能否区分 root、platform、组件级 providedIn。
回答框架① DI 本质是控制反转(IoC),由注入器创建并维护实例;② 模块/组件声明 providers 形成注入器树,子注入器可继承父级;③ 推荐 providedIn: 'root' 单例,避免重复实例。
示例回答"Angular 通过注入器树实现 DI。例如将 UserService 通过 providedIn: 'root' 注册,整个应用共享一个实例;若在组件 providers 中声明,该组件及其子组件会获得新实例,实现隔离作用域。"
可能追问- 如何实现非单例(如每个组件独立实例)?
- @Optional 和 @Host 装饰器的用途?
- 自定义注入令牌(InjectionToken)的场景?
避坑提醒❌ 别只说“依赖注入就是把对象传进来”——要提注入器树、层级、providedIn。❌ 不要混淆 providedIn: 'root' 和 providedIn: 'any'(Angular 14+ 中 ‘any’ 每个惰性模块独立实例)。

Q2:父子组件、兄弟组件、跨级组件如何通信?

考察点是否掌握 @Input/@Output、模板变量、ViewChild、Service + Subject/BehaviorSubject、ng-content、路由参数、Redux 模式。
回答框架① 父子:@Input 传数据,@Output + EventEmitter 传事件;② 兄弟:共享 Service(Subject)或 Redux(NgRx);③ 跨级:@Input 逐级传递、Service 注入、@ContentChild 或路由参数。
示例回答"父子通信用 @Input 传值、@Output 发事件。兄弟组件常用共享 Service:定义一个 Subject,一方 emit,一方 subscribe。跨级可通过路由参数或 Service + providedIn: 'root' 实现。"
可能追问- 为什么推荐使用 BehaviorSubject 而不是 Subject?
- 如何防止内存泄漏?
- 何时应该用 NgRx 而不是简单 Service?
避坑提醒❌ 不要在子组件直接修改父组件传入的对象(@Input 可变引用)——应使用不可变更新或事件回调。❌ 兄弟通信滥用 @Output 向上传至公共祖先再下传,导致代码混乱;优先用 Service。

Q3:Angular 生命周期钩子的执行顺序?如何利用它们进行性能优化?

考察点是否牢记钩子顺序,理解变更检测触发时机;能否结合 ngOnDestroy 取消订阅、ngDoCheck 自定义检测、ngAfterViewInit 操作 DOM。
回答框架① 顺序:constructor → ngOnChanges → ngOnInit → ngDoCheck → ngAfterContentInit → ngAfterContentChecked → ngAfterViewInit → ngAfterViewChecked → ngOnDestroy;② 优化点:在 ngOnDestroy 取消订阅;避免在 ngDoCheck 中执行耗时逻辑;用 ChangeDetectionStrategy.OnPush 减少检测。
示例回答"生命周期顺序固定:constructor 先于 ngOnChanges 等。我常在 ngOnInit 初始化数据,在 ngOnDestroy 中使用 takeUntil 取消订阅避免内存泄漏。大厂面试特别关注 OnPush 策略和 detach 手动控制变更检测。"
可能追问- 为什么 constructor 不属于生命周期钩子?
- 父组件 @ViewChild 的子组件在哪个钩子后可访问?
- 如何实现自定义变更检测策略?
- 公司侧重点:如何保证动画/定时器不导致性能问题?
避坑提醒❌ 别把 constructor 当钩子——它用于 DI,不涉及模板绑定。❌ 不要在 ngAfterViewChecked 里修改属性(会触发循环)。❌ 大厂关注可维护性,回答需强调“按需检测”而非“禁用变更检测”。
💡 公司侧重点差异:
  • 大厂(BAT/TMD): 性能敏感,必问 OnPush、ngDoCheck 业务使用、懒加载与 DI 实例管理;关注源码理解(如注入器树实现)。
  • 中型企业: 看重组件化设计、Service 分层、可测试性(如何 mock 依赖)。
  • 外企/出海: 常问国际化(i18n)与 DI 配置、响应式表单 + 生命周期结合。
⚠️ 高频失分点:
  • 分不清 ngAfterContentInit 与 ngAfterViewInit(Content vs View,投影内容 vs 组件视图)。
  • 组件通信遗漏 ng-content 投影方式(多 slot 投影)。
  • 依赖注入不理解 @Injectable 的 providedIn 与模块 providers 区别。