> ## Documentation Index
> Fetch the complete documentation index at: https://resources.devweekends.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 31. Interview Questions

> Comprehensive Angular interview preparation guide

<Frame>
  <img src="https://mintcdn.com/devweeekends/AEOaWh79Ur7CdHHv/images/courses/angular-crash-course/angular-hero.svg?fit=max&auto=format&n=AEOaWh79Ur7CdHHv&q=85&s=32645ae19fa9bc25d3ec281022aba371" alt="Interview Questions" width="1200" height="400" data-path="images/courses/angular-crash-course/angular-hero.svg" />
</Frame>

## Interview Questions Overview

<Info>
  **Estimated Time**: 4 hours | **Difficulty**: All Levels | **Prerequisites**: Complete Angular Course
</Info>

This comprehensive guide covers Angular interview questions from basic to advanced levels, helping you prepare for technical interviews at any stage of your career.

**How to use this guide**: Do not memorize answers -- interviewers can spot rehearsed responses immediately. Instead, understand the *why* behind each answer so you can reason through variations. A senior engineer would say: "I know the trade-offs and can explain when I would choose differently." That framing is worth more than any perfect textbook answer.

***

## Core Angular Concepts

### Q1: What is Angular and how does it differ from AngularJS?

<Accordion title="Answer">
  **Angular** is a TypeScript-based platform for building web applications, completely rewritten from AngularJS.

  Key differences:

  * **Architecture**: Angular uses component-based architecture; AngularJS uses MVC
  * **Language**: Angular uses TypeScript; AngularJS uses JavaScript
  * **Mobile**: Angular supports mobile development; AngularJS doesn't
  * **Performance**: Angular has improved change detection and AOT compilation
  * **CLI**: Angular has powerful CLI; AngularJS doesn't have official CLI
</Accordion>

### Q2: Explain the Angular component lifecycle hooks

<Accordion title="Answer">
  ```typescript theme={null}
  @Component({...})
  export class ExampleComponent implements OnInit, OnChanges, OnDestroy {
    // Called once before ngOnInit when inputs change
    ngOnChanges(changes: SimpleChanges) {}
    
    // Called once after first ngOnChanges
    ngOnInit() {}
    
    // Called every change detection cycle
    ngDoCheck() {}
    
    // Called once after first ngDoCheck
    ngAfterContentInit() {}
    
    // Called after every ngDoCheck
    ngAfterContentChecked() {}
    
    // Called once after first ngAfterContentChecked
    ngAfterViewInit() {}
    
    // Called after every ngAfterContentChecked
    ngAfterViewChecked() {}
    
    // Called before component is destroyed
    ngOnDestroy() {}
  }
  ```

  **Order**: constructor → ngOnChanges → ngOnInit → ngDoCheck → ngAfterContentInit → ngAfterContentChecked → ngAfterViewInit → ngAfterViewChecked → ngOnDestroy
</Accordion>

### Q3: What are Angular Signals?

<Accordion title="Answer">
  Signals are a reactive primitive introduced in Angular 16 for fine-grained reactivity.

  ```typescript theme={null}
  // Creating signals
  const count = signal(0);
  const name = signal('Angular');

  // Reading signals
  console.log(count()); // 0

  // Updating signals
  count.set(5);
  count.update(v => v + 1);

  // Computed signals (derived values)
  const doubled = computed(() => count() * 2);

  // Effects (side effects)
  effect(() => {
    console.log(`Count is: ${count()}`);
  });
  ```

  **Benefits**:

  * Fine-grained reactivity (only affected components update)
  * Better performance than Zone.js change detection
  * Simpler mental model than RxJS for synchronous state
  * Lazy evaluation of computed values (only recompute when read AND dependencies changed)

  **What a senior engineer would add**: "Signals are not a replacement for RxJS -- they solve different problems. Signals are for synchronous, UI-driven state (a counter, a filter value, a selected item). RxJS is for asynchronous streams (HTTP responses, WebSocket messages, debounced user input). The best Angular codebases use both: signals for component state, RxJS for async pipelines, and `toSignal()` / `toObservable()` as bridges between them."
</Accordion>

### Q4: Explain the difference between OnPush and Default change detection

<Accordion title="Answer">
  **Default Strategy**: Angular checks the entire component tree on every change detection cycle.

  **OnPush Strategy**: Component only checked when:

  1. Input reference changes
  2. Event from component or child
  3. Async pipe emits new value
  4. Manual `markForCheck()` or `detectChanges()`

  ```typescript theme={null}
  @Component({
    changeDetection: ChangeDetectionStrategy.OnPush
  })
  export class OptimizedComponent {
    data = input<Data>(); // Only triggers on reference change
    
    // Manual trigger if needed
    private cdr = inject(ChangeDetectorRef);
    
    forceUpdate() {
      this.cdr.markForCheck();
    }
  }
  ```

  **Best Practice**: Use OnPush everywhere with immutable data patterns.

  **Interview tip**: If asked "when would you NOT use OnPush?", the honest answer is "almost never in new code." The only exception is rapid prototyping where you are mutating objects in place and do not want to debug why the UI is not updating. But any production code should use OnPush -- it turns change detection from "check everything every time" to "check this component only when its inputs change." That is the difference between O(n) and O(1) per component.
</Accordion>

***

## Dependency Injection

### Q5: What is Dependency Injection and how does Angular implement it?

<Accordion title="Answer">
  DI is a design pattern where dependencies are provided to a class rather than created by it.

  ```typescript theme={null}
  // Service definition
  @Injectable({ providedIn: 'root' })
  export class UserService {
    getUser(id: string): Observable<User> { ... }
  }

  // Injection in component
  @Component({...})
  export class UserComponent {
    private userService = inject(UserService);
    
    // Or via constructor
    constructor(private userService: UserService) {}
  }
  ```

  **Hierarchical Injector**:

  * Root level: `providedIn: 'root'` (singleton)
  * Module level: `providers` array in NgModule
  * Component level: `providers` in component (new instance per component)

  **Benefits**: Loose coupling, testability, reusability
</Accordion>

### Q6: Explain providedIn options

<Accordion title="Answer">
  ```typescript theme={null}
  // Singleton for entire app
  @Injectable({ providedIn: 'root' })

  // Singleton per lazy-loaded module
  @Injectable({ providedIn: 'any' })

  // Provided to specific module
  @Injectable({ providedIn: SomeModule })

  // Platform level (shared across apps)
  @Injectable({ providedIn: 'platform' })

  // Not automatically provided (must add to providers array)
  @Injectable()
  ```
</Accordion>

***

## Templates & Data Binding

### Q7: Explain the different types of data binding in Angular

<Accordion title="Answer">
  ```html theme={null}
  <!-- 1. Interpolation (one-way) -->
  <p>{{ message }}</p>

  <!-- 2. Property Binding (one-way) -->
  <img [src]="imageUrl">
  <button [disabled]="isDisabled">

  <!-- 3. Event Binding (one-way) -->
  <button (click)="onClick()">

  <!-- 4. Two-way Binding -->
  <input [(ngModel)]="name">
  <!-- Equivalent to: -->
  <input [ngModel]="name" (ngModelChange)="name = $event">

  <!-- 5. Attribute Binding -->
  <td [attr.colspan]="colSpan">

  <!-- 6. Class Binding -->
  <div [class.active]="isActive">

  <!-- 7. Style Binding -->
  <div [style.color]="textColor">
  ```
</Accordion>

### Q8: What is the difference between ng-template, ng-container, and ng-content?

<Accordion title="Answer">
  **ng-template**: Defines a template that is not rendered by default

  ```html theme={null}
  <ng-template #myTemplate let-name="name">
    <p>Hello, {{ name }}</p>
  </ng-template>
  <ng-container *ngTemplateOutlet="myTemplate; context: {name: 'Angular'}"/>
  ```

  **ng-container**: Logical grouping without adding extra DOM elements

  ```html theme={null}
  <ng-container *ngIf="condition">
    <p>No wrapper element added</p>
  </ng-container>
  ```

  **ng-content**: Content projection (transclusion)

  ```html theme={null}
  <!-- parent-component.html -->
  <child-component>
    <p>This content is projected</p>
  </child-component>

  <!-- child-component.html -->
  <div class="wrapper">
    <ng-content></ng-content>
  </div>
  ```
</Accordion>

***

## Routing

### Q9: What are Route Guards and their types?

<Accordion title="Answer">
  ```typescript theme={null}
  // CanActivate - Control access to route
  export const authGuard: CanActivateFn = (route, state) => {
    const auth = inject(AuthService);
    return auth.isLoggedIn() ? true : inject(Router).createUrlTree(['/login']);
  };

  // CanActivateChild - Control access to child routes
  export const adminGuard: CanActivateChildFn = () => {
    return inject(AuthService).isAdmin();
  };

  // CanDeactivate - Prevent leaving route
  export const unsavedChangesGuard: CanDeactivateFn<HasUnsavedChanges> = (component) => {
    return component.hasUnsavedChanges() 
      ? confirm('Discard changes?') 
      : true;
  };

  // CanMatch - Prevent route matching entirely
  export const featureGuard: CanMatchFn = () => {
    return inject(FeatureService).isEnabled('new-feature');
  };

  // Resolve - Pre-fetch data before activation
  export const userResolver: ResolveFn<User> = (route) => {
    return inject(UserService).getUser(route.params['id']);
  };

  // Routes configuration
  const routes: Routes = [
    {
      path: 'admin',
      canActivate: [authGuard],
      canActivateChild: [adminGuard],
      canMatch: [featureGuard],
      children: [...]
    }
  ];
  ```
</Accordion>

### Q10: Explain lazy loading in Angular

<Accordion title="Answer">
  ```typescript theme={null}
  // Lazy load routes
  const routes: Routes = [
    {
      path: 'products',
      loadChildren: () => import('./products/products.routes')
        .then(m => m.PRODUCTS_ROUTES)
    },
    {
      path: 'admin',
      loadComponent: () => import('./admin/admin.component')
        .then(m => m.AdminComponent)
    }
  ];

  // Preloading strategies
  @NgModule({
    imports: [
      RouterModule.forRoot(routes, {
        preloadingStrategy: PreloadAllModules
        // Or custom: CustomPreloadingStrategy
      })
    ]
  })

  // Deferrable views (Angular 17+)
  @defer (on viewport) {
    <app-heavy-component />
  } @placeholder {
    <app-skeleton />
  }
  ```
</Accordion>

***

## RxJS & HTTP

### Q11: What is the difference between Subject, BehaviorSubject, and ReplaySubject?

This is one of the most frequently asked RxJS questions. The key mental model: all Subjects are both Observables (you can subscribe to them) and Observers (you can push values into them). They differ in what happens to **late subscribers** -- subscribers that join after values have already been emitted.

<Accordion title="Answer">
  ```typescript theme={null}
  // Subject - No initial value, late subscribers miss past emissions
  const subject = new Subject<number>();
  subject.next(1);
  subject.subscribe(v => console.log(v)); // Won't receive 1
  subject.next(2); // Logs: 2

  // BehaviorSubject - Has initial/current value
  const behavior = new BehaviorSubject<number>(0);
  behavior.next(1);
  behavior.subscribe(v => console.log(v)); // Logs: 1 (current value)
  behavior.getValue(); // Returns current value: 1

  // ReplaySubject - Replays N values to new subscribers
  const replay = new ReplaySubject<number>(2); // Buffer size 2
  replay.next(1);
  replay.next(2);
  replay.next(3);
  replay.subscribe(v => console.log(v)); // Logs: 2, 3

  // AsyncSubject - Only emits last value on completion
  const async = new AsyncSubject<number>();
  async.next(1);
  async.next(2);
  async.subscribe(v => console.log(v)); // Nothing yet
  async.complete(); // Now logs: 2
  ```
</Accordion>

### Q12: Explain common RxJS operators

The trick to mastering RxJS operators is to group them by *what problem they solve*, not memorize them alphabetically. In an interview, showing you can pick the right operator for a scenario is far more impressive than listing 20 operator names.

<Accordion title="Answer">
  ```typescript theme={null}
  // Transformation
  map(x => x * 2)              // Transform each value
  switchMap(x => http.get(x))  // Switch to new observable, cancel previous
  mergeMap(x => http.get(x))   // Merge all inner observables
  concatMap(x => http.get(x))  // Queue inner observables sequentially

  // Filtering
  filter(x => x > 0)           // Filter values
  distinctUntilChanged()       // Only emit when value changes
  debounceTime(300)            // Wait for pause in emissions
  throttleTime(300)            // Rate limit emissions
  take(5)                      // Take first N values
  takeUntil(destroy$)          // Take until signal

  // Combination
  combineLatest([a$, b$])      // Emit when any source emits
  forkJoin([a$, b$])           // Emit when all complete
  merge(a$, b$)                // Merge multiple streams
  withLatestFrom(other$)       // Combine with latest from another

  // Error Handling
  catchError(err => of(null))  // Handle errors
  retry(3)                     // Retry on error
  retryWhen(...)               // Custom retry logic

  // Utility
  tap(x => console.log(x))     // Side effects
  shareReplay(1)               // Share and cache last value
  ```
</Accordion>

***

## Testing

### Q13: How do you test Angular components?

<Accordion title="Answer">
  ```typescript theme={null}
  describe('UserComponent', () => {
    let component: UserComponent;
    let fixture: ComponentFixture<UserComponent>;
    let userServiceSpy: jasmine.SpyObj<UserService>;
    
    beforeEach(async () => {
      userServiceSpy = jasmine.createSpyObj('UserService', ['getUser']);
      userServiceSpy.getUser.and.returnValue(of({ id: '1', name: 'Test' }));
      
      await TestBed.configureTestingModule({
        imports: [UserComponent],
        providers: [
          { provide: UserService, useValue: userServiceSpy }
        ]
      }).compileComponents();
      
      fixture = TestBed.createComponent(UserComponent);
      component = fixture.componentInstance;
    });
    
    it('should create', () => {
      expect(component).toBeTruthy();
    });
    
    it('should display user name', () => {
      fixture.componentRef.setInput('userId', '1');
      fixture.detectChanges();
      
      const nameElement = fixture.nativeElement.querySelector('.user-name');
      expect(nameElement.textContent).toContain('Test');
    });
    
    it('should call service on init', () => {
      fixture.componentRef.setInput('userId', '1');
      fixture.detectChanges();
      
      expect(userServiceSpy.getUser).toHaveBeenCalledWith('1');
    });
  });
  ```
</Accordion>

***

## Performance

### Q14: How do you optimize Angular application performance?

<Accordion title="Answer">
  **Build-time optimizations:**

  * AOT compilation
  * Tree shaking
  * Code splitting / lazy loading
  * Bundle analysis and optimization

  **Runtime optimizations:**

  ```typescript theme={null}
  // 1. OnPush change detection
  @Component({
    changeDetection: ChangeDetectionStrategy.OnPush
  })

  // 2. TrackBy for lists
  @for (item of items(); track item.id) {
    <app-item [item]="item" />
  }

  // 3. Signals for reactive state
  count = signal(0);
  doubled = computed(() => this.count() * 2);

  // 4. Deferrable views
  @defer (on viewport) {
    <heavy-component />
  }

  // 5. Virtual scrolling for large lists
  <cdk-virtual-scroll-viewport itemSize="50">
    <div *cdkVirtualFor="let item of items">{{ item }}</div>
  </cdk-virtual-scroll-viewport>

  // 6. Pure pipes
  @Pipe({ pure: true })

  // 7. Unsubscribe properly
  takeUntilDestroyed(this.destroyRef)
  ```
</Accordion>

***

## Advanced Topics

### Q15: What is Zone.js and how does Angular use it?

<Accordion title="Answer">
  Zone.js is a library that patches async APIs (setTimeout, Promise, XHR, etc.) to notify Angular when async operations complete.

  ```typescript theme={null}
  // Zone.js patches these to trigger change detection:
  setTimeout(() => {})
  Promise.resolve().then(() => {})
  fetch('/api').then(() => {})
  element.addEventListener('click', () => {})

  // Running outside Angular zone (for performance)
  @Component({...})
  export class PerformanceComponent {
    private ngZone = inject(NgZone);
    
    heavyOperation() {
      this.ngZone.runOutsideAngular(() => {
        // This won't trigger change detection
        setInterval(() => this.trackMouse(), 10);
      });
    }
    
    updateUI() {
      this.ngZone.run(() => {
        // This triggers change detection
        this.value = 'updated';
      });
    }
  }
  ```

  **Zoneless Angular (experimental in v18)**:

  ```typescript theme={null}
  bootstrapApplication(App, {
    providers: [
      provideExperimentalZonelessChangeDetection()
    ]
  });
  ```
</Accordion>

### Q16: Explain Angular SSR and Hydration

<Accordion title="Answer">
  **Server-Side Rendering (SSR)** renders the application on the server, sending HTML to the client.

  **Hydration** reuses the server-rendered DOM instead of re-creating it.

  ```typescript theme={null}
  // app.config.server.ts
  export const config: ApplicationConfig = {
    providers: [
      provideServerRendering(),
      provideClientHydration()
    ]
  };

  // Benefits:
  // - Better SEO (search engines see content)
  // - Faster First Contentful Paint
  // - Better Core Web Vitals
  // - Works with JavaScript disabled

  // Hydration skipping for dynamic content
  @Component({
    host: { ngSkipHydration: 'true' }
  })
  export class DynamicComponent {}
  ```
</Accordion>

***

## Coding Challenges

### Challenge 1: Implement a debounced search

<Accordion title="Solution">
  ```typescript theme={null}
  @Component({
    template: `
      <input [formControl]="searchControl" placeholder="Search...">
      @for (result of results(); track result.id) {
        <div>{{ result.name }}</div>
      }
    `
  })
  export class SearchComponent {
    private searchService = inject(SearchService);
    private destroyRef = inject(DestroyRef);
    
    searchControl = new FormControl('');
    results = signal<SearchResult[]>([]);
    
    ngOnInit() {
      this.searchControl.valueChanges.pipe(
        debounceTime(300),
        distinctUntilChanged(),
        filter(term => term.length >= 2),
        switchMap(term => this.searchService.search(term)),
        takeUntilDestroyed(this.destroyRef)
      ).subscribe(results => this.results.set(results));
    }
  }
  ```
</Accordion>

### Challenge 2: Create a reusable modal service

<Accordion title="Solution">
  ```typescript theme={null}
  @Injectable({ providedIn: 'root' })
  export class ModalService {
    private vcr!: ViewContainerRef;
    
    setContainer(vcr: ViewContainerRef) {
      this.vcr = vcr;
    }
    
    open<T, R>(component: Type<T>, data?: Partial<T>): Observable<R> {
      const subject = new Subject<R>();
      const ref = this.vcr.createComponent(component);
      
      if (data) {
        Object.entries(data).forEach(([key, value]) => {
          ref.setInput(key, value);
        });
      }
      
      // Assuming component has 'closed' output
      ref.instance.closed?.subscribe((result: R) => {
        subject.next(result);
        subject.complete();
        ref.destroy();
      });
      
      return subject.asObservable();
    }
  }
  ```
</Accordion>

***

## Tips for Success

<CardGroup cols={2}>
  <Card title="Understand Fundamentals" icon="graduation-cap">
    Know DI, change detection, and component lifecycle deeply
  </Card>

  <Card title="Practice Coding" icon="code">
    Be ready to write code on whiteboard or shared editor
  </Card>

  <Card title="Know RxJS" icon="wave-square">
    Understand operators and when to use them
  </Card>

  <Card title="Discuss Trade-offs" icon="scale-balanced">
    Show you can evaluate different approaches
  </Card>
</CardGroup>

***

<Card title="Next: Best Practices" icon="arrow-right" href="/courses/angular-crash-course/32-best-practices">
  Learn Angular best practices and style guide
</Card>
