Angular 19 면접 질문: Signals, SSR과 반드시 알아야 할 개념

가장 자주 나오는 Angular 19 면접 질문: Signals, 점진적 하이드레이션, zoneless 변경 감지, 새로운 리액티브 API. 코드 예제와 기대되는 답변까지 함께 정리합니다.

Angular 19 면접 질문: Signals, SSR, 점진적 하이드레이션

2026년 Angular 면접은 단순한 컴포넌트와 서비스 차원을 훨씬 넘어섭니다. 2024년 11월에 출시된 Angular 19는 안정화된 Signals, 점진적 하이드레이션을 갖춘 SSR, zoneless 변경 감지라는 근본적인 아키텍처 전환을 가져왔습니다. 이 개념들을 숙지했는지 여부가 미들 레벨과 시니어 레벨 후보를 가르는 기준이 됩니다.

2026년 면접관이 평가하는 포인트

Angular 19 질문은 세 가지 영역을 겨냥합니다. Signals를 통한 세밀한 리액티비티, 점진적 하이드레이션을 통한 SSR 성능, 그리고 Zone.js 없이 애플리케이션을 설계하는 능력입니다. 기대되는 답변은 단순한 문법 지식이 아니라 아키텍처적 이해를 보여줍니다.

Angular 19 Signals: 새로운 리액티비티 모델

Signals는 변경 감지가 도입된 이래 Angular에서 가장 본질적인 변화입니다. Signal은 값이 변경될 때 자동으로 컨슈머에게 알림을 보내는 동기 리액티브 값입니다.

전형적인 질문: "Signal과 RxJS Observable의 차이는 무엇입니까?"

기대되는 답변은 두 모델을 명확히 구분합니다.

signals-vs-observables.tstypescript
import { signal, computed, effect } from '@angular/core';

// Signal: synchronous, value always available
const count = signal(0);
const doubled = computed(() => count() * 2); // Recomputed only when count changes

// Effect: reacts to signal changes
effect(() => {
  console.log(`Count: ${count()}, Doubled: ${doubled()}`);
});

count.set(5); // Immediate, synchronous notification

Signals는 세밀한 의존성 그래프를 사용합니다. retry, debounce, merge 등 복잡한 비동기 워크플로우를 다루는 RxJS와 달리, Signals는 동기적인 UI 리액티비티를 최적화합니다. Angular 19는 컴포넌트 상태에는 Signals를, 비동기 스트림 (HTTP 요청, WebSocket)에는 RxJS를 권장합니다.

Signal Inputs와 Queries: @Input()에서 마이그레이션

Angular 19는 input, output, query를 위한 signal 기반 API를 안정화했습니다. 이 질문은 면접에서 꾸준히 등장합니다.

전형적인 질문: "기존 @Input()을 Signal Input으로 어떻게 마이그레이션합니까?"

user-card.component.tstypescript
import { Component, input, computed } from '@angular/core';

@Component({
  selector: 'app-user-card',
  template: `
    <div class="card">
      <h3>{{ fullName() }}</h3>
      <span>{{ role() }}</span>
    </div>
  `
})
export class UserCardComponent {
  // Signal inputs: strict typing, optional default value
  firstName = input.required<string>();
  lastName = input.required<string>();
  role = input<string>('developer'); // Default value

  // Computed derived from inputs: automatically recomputed
  fullName = computed(() => `${this.firstName()} ${this.lastName()}`);
}

핵심 이점은 Signal Inputs가 라이프사이클 훅 없이도 computed() 값을 직접 만들 수 있다는 점입니다. 입력 변화에 반응하기 위해 더 이상 ngOnChanges가 필요하지 않습니다. Angular는 마이그레이션을 자동화하기 위해 signal-input-migration schematic을 제공합니다.

linkedSignal: 의존 상태 동기화

linkedSignal은 소스에 연결된 쓰기 가능한 signal을 만드는 Angular 19의 실험적 API입니다. 이 개념은 시니어 레벨 면접에서 자주 등장합니다.

전형적인 질문: "linkedSignal로 변경 가능한 파생 상태를 어떻게 다룹니까?"

product-filter.component.tstypescript
import { signal, linkedSignal } from '@angular/core';

// Category list that can change
const categories = signal(['frontend', 'backend', 'devops']);

// Linked selection: resets when categories change
const selectedCategory = linkedSignal({
  source: categories,
  computation: (cats) => cats[0] // Reset to first element
});

// Manual modification still possible
selectedCategory.set('backend');

// When categories changes, selectedCategory resets automatically
categories.set(['mobile', 'data', 'cloud']);
// selectedCategory() === 'mobile'

구체적인 사용 사례: 소스 리스트가 바뀌면 선택이 리셋되는 필터 드롭다운입니다. linkedSignal이 없을 때 이 패턴은 effect() 안에서 set()을 호출해야 했고, 이는 업데이트 루프를 만드는 안티 패턴이었습니다.

면접 함정: effect() 안에서 set()

effect() 내부에서 signal.set()을 호출하는 것은 Angular가 감지하는 안티 패턴입니다. 프레임워크는 개발 모드에서 경고를 출력합니다. 올바른 해법은 파생 값이 쓰기 가능해야 하는지에 따라 linkedSignal 또는 computed()를 사용하는 것입니다.

Resource API: Signals로 비동기 데이터 로드

Angular 19는 비동기 데이터 로딩을 위한 실험적 API resource를 도입했습니다. 이 API는 컴포넌트의 전통적인 service + subscribe 패턴을 대체합니다.

user-profile.component.tstypescript
import { resource, signal } from '@angular/core';
import { inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';

const userId = signal(42);
const http = inject(HttpClient);

// Resource: links a source signal to an async loader
const userResource = resource({
  request: () => ({ id: userId() }),  // Recomputed when userId changes
  loader: async ({ request }) => {
    const response = await fetch(`/api/users/${request.id}`);
    return response.json();
  }
});

// Access in template
// userResource.value()   -> data (or undefined)
// userResource.isLoading() -> boolean
// userResource.error()    -> error if any

면접에서 resourcerxResource (RxJS 버전)에 대한 지식을 보여주는 것은 능동적인 기술 트래킹의 증거입니다. rxResource는 Observable을 로더로 사용하므로 기존 RxJS 코드베이스를 가진 팀에 유용합니다.

Angular 면접 준비가 되셨나요?

인터랙티브 시뮬레이터, flashcards, 기술 테스트로 연습하세요.

Angular 19의 SSR과 점진적 하이드레이션

Angular 19는 developer preview 단계의 점진적 하이드레이션으로 SSR을 한 단계 끌어올립니다. Google Search 규모에서 검증된 이 기능은 면접에서 점점 자주 등장하는 주제입니다.

전형적인 질문: "Angular 19의 점진적 하이드레이션은 어떻게 동작합니까?"

전통적인 하이드레이션은 서버 렌더링 이후 클라이언트에서 컴포넌트 트리 전체를 다시 만듭니다. 점진적 하이드레이션은 화면에 보이거나 상호작용이 발생한 시점에 필요한 컴포넌트만 하이드레이트합니다.

product-page.component.tstypescript
import { Component } from '@angular/core';

@Component({
  template: `
    <app-header />
    <app-product-details [id]="productId" />

    <!-- Hydrated only when visible in viewport -->
    @defer (on viewport) {
      <app-reviews [productId]="productId" />
    }

    <!-- Hydrated only on user interaction -->
    @defer (on interaction) {
      <app-comment-form />
    }
  `
})
export class ProductPageComponent {
  productId = 'angular-19-guide';
}

@defer 디렉티브는 하이드레이션 시점을 정밀하게 제어합니다. 사용 가능한 트리거: on viewport (가시), on interaction (클릭, 포커스), on idle (브라우저 유휴), on timer(5s) (지연). 콘텐츠는 하이드레이션 전에도 정적인 HTML로 계속 표시되므로 콘텐츠가 깜박이지 않습니다.

라우트 단위 render mode: 라우트별 세밀한 SSR

Angular 19는 라우트 단위의 render mode를 도입해 동일한 애플리케이션 안에서 SSR, SSG, CSR이 공존할 수 있게 했습니다.

app.routes.server.tstypescript
import { RenderMode, ServerRoute } from '@angular/ssr';

export const serverRoutes: ServerRoute[] = [
  // Marketing pages: pre-rendered at build time (SSG)
  { path: '', renderMode: RenderMode.Prerender },
  { path: 'pricing', renderMode: RenderMode.Prerender },

  // Dashboard: server-rendered on each request (SSR)
  { path: 'dashboard/**', renderMode: RenderMode.Server },

  // Interactive editor: client-side only (CSR)
  { path: 'editor/**', renderMode: RenderMode.Client },
];

면접에서 라우트별 render mode 선택을 정당화할 수 있다는 것은 성능, SEO, 인터랙티비티 사이의 트레이드오프를 이해하고 있음을 보여줍니다. 정적 페이지 (랜딩, 블로그)는 prerender의 이점을 누립니다. 사용자 데이터를 가진 동적 페이지는 SSR을 사용합니다. 인터랙티브한 애플리케이션은 CSR을 유지합니다.

Zoneless 변경 감지: Zone.js 없는 아키텍처

Zoneless 변경 감지는 Angular 19에서 가장 중요한 아키텍처적 진화입니다. 시니어 면접에서 이 질문은 필수가 되었습니다.

전형적인 질문: "Zone.js 없이 변경 감지는 어떻게 작동합니까?"

main.tstypescript
import { bootstrapApplication } from '@angular/platform-browser';
import {
  provideExperimentalZonelessChangeDetection
} from '@angular/core';
import { AppComponent } from './app.component';

bootstrapApplication(AppComponent, {
  providers: [
    provideExperimentalZonelessChangeDetection()
  ]
});

Zone.js가 없으면 Angular는 더 이상 브라우저의 비동기 API (setTimeout, Promise, addEventListener)에 패치를 적용하지 않습니다. 변경 감지는 오직 Signals를 통해서만 트리거됩니다. 측정 가능한 이점:

  • 번들 크기 10-15 KB 감소 (zone.js 제거)
  • Zone.js 프레임이 없는 깔끔한 스택 트레이스
  • 타깃팅된 변경 감지: 변경된 Signal의 영향을 받는 컴포넌트만 다시 렌더링
Angular 20.2: zoneless가 안정화

Angular 20.2부터 zoneless 모드는 provideZonelessChangeDetection() (Experimental 접두사 없이)으로 안정화되었습니다. 이 진화 과정을 면접에서 언급하면 생태계에 대한 능동적인 추적을 보여줍니다.

기본값으로 standalone: NgModules의 종말

Angular 19는 standalone 컴포넌트를 기본 동작으로 만들었습니다. standalone: true 플래그가 더 이상 필요하지 않습니다. 이 결정은 아키텍처를 단순화하고 보일러플레이트를 줄입니다.

전형적인 질문: "standalone-by-default는 Angular 애플리케이션 아키텍처에 어떤 영향을 줍니까?"

dashboard.component.tstypescript
@Component({
  selector: 'app-dashboard',
  imports: [CommonModule, RouterModule, UserCardComponent],
  template: `
    <nav>
      <a routerLink="/home">Home</a>
    </nav>
    @for (user of users(); track user.id) {
      <app-user-card [firstName]="user.firstName" [lastName]="user.lastName" />
    }
  `
})
export class DashboardComponent {
  users = signal<User[]>([]);
}

각 컴포넌트는 imports를 통해 의존성을 명시적으로 선언합니다. NgModules는 하위 호환성을 위해 계속 사용할 수 있지만, 새로운 Angular 19+ 애플리케이션에서는 더 이상 필요하지 않습니다. 면접에서는 빅뱅 방식 대신 컴포넌트 단위의 점진적 마이그레이션을 설명할 수 있는 능력이 높이 평가됩니다.

Angular 19 면접을 위한 답변 전략

기술 면접관은 Angular 19에 대해 세 가지 차원을 평가합니다.

  • 아키텍처적 이해: Signals가 단순한 사용법이 아니라 왜 점진적으로 Zone.js를 대체하는지를 설명할 수 있어야 합니다
  • 트레이드오프: computed(), linkedSignal, effect()를 언제 사용할지, 그리고 RxJS를 언제 유지할지 알아야 합니다
  • 마이그레이션: 전통적인 Angular 애플리케이션에서 Signals와 zoneless 모드로의 점진적 마이그레이션 전략을 설명해야 합니다

핵심은 공식 Angular 문서를 그대로 외워서 말하지 않는 것입니다. 모든 답변은 복잡한 폼, SSR이 적용된 e-커머스 페이지, 실시간 대시보드 등 실제 프로젝트에서 가져온 구체적인 사용 사례로 뒷받침해야 합니다.

면접 전 Angular의 기초 개념을 점검하려면 Angular 면접 질문 25선 가이드를 참고하십시오.

결론

  • Angular 19의 Signals는 @Input() + ngOnChanges 패턴을 세밀한 동기 리액티브 모델로 대체합니다. signal(), computed(), input()이 사용 사례의 90%를 커버합니다
  • linkedSignaleffect() + set() 안티 패턴에 의존하지 않고 변경 가능한 파생 상태를 해결합니다
  • @defer를 활용한 점진적 하이드레이션은 SEO를 희생하지 않으면서 Time to Interactive를 줄입니다. 각 컴포넌트는 자신의 트리거에 따라 하이드레이트됩니다
  • zoneless 모드는 번들에서 Zone.js를 제거하고 변경 감지를 Signal의 영향을 받는 컴포넌트로만 한정합니다
  • 라우트 단위 render mode는 페이지별 요구 사항에 따라 같은 애플리케이션에서 SSG, SSR, CSR을 혼합할 수 있게 합니다
  • standalone-by-default 컴포넌트는 새로운 애플리케이션에서 NgModules의 필요를 없앱니다
  • 면접에서는 트레이드오프를 보여주는 것 (Signals vs RxJS, SSR vs CSR, zoneless vs Zone.js)이 문법보다 중요합니다

연습을 시작하세요!

면접 시뮬레이터와 기술 테스트로 지식을 테스트하세요.

태그

#angular
#interview
#signals
#ssr
#angular-19

공유

관련 기사